所以我有一个像这样的pandas数据框:
id_1 id_2 value1 value2
1 2 100 NAN
1 2 NAN 101
10 20 200 NAN
10 20 NAN 202
10 2 345 345
我想要一个这样的数据框:
id_1 id_2 value1 value2
1 2 100 101
10 20 200 202
a b c d
基本上,如果两个ID列都匹配,那么肯定会出现value-nan
vs nan-value
情况,我想通过替换nans
来组合行。
pandas是否有实用功能?它不是堆叠或融化。也许转动,但我需要两个空位。我想保留任何没有两个indeces匹配的行。
答案 0 :(得分:0)
单向(df是您的初始数据帧):
df1=df.dropna(subset=["value1"]).drop("value2",axis=1)
df2=df.dropna(subset=["value2"]).drop("value1",axis=1)
dfNew=pd.concat([df1,df2],axis=1)
答案 1 :(得分:0)
我认为没有一个命令可以达到您的目的,并且有很多不同的方法可以实现这一目标。但是,您可以互相使用melt
和pivot
:
id_vars = ["id_1", "id_2"]
melted = df.melt(id_vars=id_vars).dropna()
pivoted = melted.pivot_table(index=id_vars, columns="variable", values="value")
print(pivoted)
variable value1 value2
id_1 id_2
1 2 100.0 101.0
10 2 345.0 345.0
20 200.0 202.0
但是,上述解决方案比以下两种解决方案慢。
首先,您可以使用前向填充ffill
填充NaN和last
以获取包含ffill
所有有效值的最后一行:
ids = ["id_1", "id_2"]
df.groupby(ids).ffill()\
.groupby(ids).last()\
.reset_index()
id_1 id_2 value1 value2
0 1 2 100 101
1 10 2 345 345
2 10 20 200 202
其次,不是分组两次(因为ffill
返回数据框),您可以使用具有相同结果的自定义apply
:
def collapse(x):
return x.ffill().iloc[-1, 2:]
df.groupby(ids).apply(collapse).reset_index()
即使我们在这里使用apply,它也是最快的解决方案(至少对于您提供的虚拟数据 - 它可能会针对较大的数据集进行不同的缩放)。
答案 2 :(得分:0)
groupby
+ first
df=df.replace('NAN',np.nan) # make sure it is np.nan not string NAN
df.groupby(['id_1','id_2'],as_index=False).first()
Out[37]:
id_1 id_2 value1 value2
0 1 2 100 101
1 10 2 345 345
2 10 20 200 202
答案 3 :(得分:0)
您也可以将它们加在一起,因为np.nan
默认会被忽略。
df = df.replace("NAN", np.nan). # turn "NAN" to np.nan
df.groupby(["id_1", "id_2"])["value1", "value2"].sum().reset_index()