gpt4 book ai didi

python - 使用 pandas,从长格式 df 中提取数据并将其添加到宽格式 df

转载 作者:太空宇宙 更新时间:2023-11-03 19:43:35 26 4
gpt4 key购买 nike

我有两个数据帧,df1 和 df2。 df1 具有以宽格式排列的重复观测值,df2 具有长格式排列的重复观测值。

import pandas as pd
df1 = pd.DataFrame({"ID":[1,2,3],"colA_1":[1,2,3],"date1":["1.1.2001", "2.1.2001","3.1.2001"],"colA_2":[4,5,6],"date2":["1.1.2002", "2.1.2002","3.1.2002"]})
df2 = pd.DataFrame({"ID":[1,1,2,2,3,3],"col1":[1,1.5,2,2.5,3,3.5],"date":["1.1.2001", "1.1.2002","2.1.2001","2.1.2002","3.1.2001","3.1.2002"], "col3":[11,12,13,14,15,16],"col4":[21,22,23,24,25,26]})

df1 看起来像:

   ID  colA_1     date1  colA_2     date2
0 1 1 1.1.2001 4 1.1.2002
1 2 2 2.1.2001 5 2.1.2002
2 3 3 3.1.2001 6 3.1.2002

df2 看起来像:

   ID  col1     date1  col3  col4
0 1 1.0 1.1.2001 11 21
1 1 1.5 1.1.2002 12 22
2 2 2.0 2.1.2001 13 23
3 2 2.5 2.1.2002 14 24
4 3 3.0 3.1.2001 15 25
5 3 3.5 3.1.2002 16 26
6 3 4.0 4.1.2002 17 27


我想从 df2“col3”中获取给定列,然后:

(1) 如果 df2 中的列“ID”和“date”与 df1 中的列“ID”和“date1”匹配,我想将该值放入 df1 中名为“colB_1”的新列中。

(2) 否则,如果 df2 中的列“ID”和“date”与 df1 中的列“ID”和“date2”匹配,我想将该值放入 df1 中名为“colB_2”的新列中。

(3) 否则,如果 df2 中的列“ID”和“日期”与(“ID”和“date1”)或(“ID”和“date2”)不匹配,我想忽略这些行.

因此,此输出数据帧 df3 的输出应如下所示:

   ID  colA_1     date1  colA_2     date2  colB_1  colB_2
0 1 1 1.1.2001 4 1.1.2002 11 12
1 2 2 2.1.2001 5 2.1.2002 13 14
2 3 3 3.1.2001 6 3.1.2002 15 16

最好的方法是什么?

我找到了this链接,但答案不适用于我的情况。我想要一种非常明确的方法来指定列匹配。我认为 df.mask 可能可以帮助我,但我不确定如何实现它。

例如:以下代码

df3 = df1.copy()
df3["colB_1"] = ""
df3["colB_2"] = ""
filter1 = (df1["ID"] == df2["ID"]) & (df1["date1"] == df2["date"])
filter2 = (df1["ID"] == df2["ID"]) & (df1["date2"] == df2["date"])
df3["colB_1"] = df.mask(filter1, other=df2["col3"])
df3["colB_2"] = df.mask(filter2, other=df2["col3"])

报错

ValueError: Can only compare identically-labeled Series objects

我问了这个问题previously ,并且它被标记为关闭;我的问题被标记为 this 的重复项一。然而,这种情况并非如此。链接问题中的答案建议使用 map或 df.merge。 map 不适用于多个条件(在我的例子中,是 ID 和日期)。当 df1 和 df2 中要合并的列名之一不同(例如“date”和“date1”)时, df.merge (为匹配多个列给出的答案)在我的情况下不起作用。

例如下面的代码:

df3 = df1.merge(df2[["ID","date","col3"]], on=['ID','date1'], how='left')

因关键错误而失败。

还值得注意的是,我将处理许多不同的文件,具有许多不同的列命名方案,并且每次都需要不同的子集。这就是为什么我想要一个明确命名列和条件的答案。

任何有关此问题的帮助将不胜感激。

最佳答案

您可以 pd.wide_to_long替换下划线后,这将取消数据帧的旋转,您可以使用该数据框与df2合并,然后使用unstackpivot返回:

m =df1.rename(columns=lambda x: x.replace('_',''))
unpiv = pd.wide_to_long(m,['colA','date'],'ID','v').reset_index()

merge_piv = (unpiv.merge(df2[['ID','date','col3']],on=['ID','date'],how='left')
.set_index(['ID','v'])['col3'].unstack().add_prefix('colB_'))

final = df1.merge(merge_piv,left_on='ID',right_index=True)
<小时/>
   ID  colA_1     date1  colA_2     date2  colB_1  colB_2
0 1 1 1.1.2001 4 1.1.2002 11 12
1 2 2 2.1.2001 5 2.1.2002 13 14
2 3 3 3.1.2001 6 3.1.2002 15 16

关于python - 使用 pandas,从长格式 df 中提取数据并将其添加到宽格式 df,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60285970/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com