[英]pandas, combine rows based on certain column values and NAN
所以我有一個像這樣的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
與nan-value
情況,我想通過替換nans
來組合行。
大熊貓有用嗎? 它不是堆疊或融化。 也許轉動,但我需要兩個空位。 我想保留任何沒有兩個indeces匹配的行。
一種方式(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)
我認為沒有一個命令可以達到您的目的,並且有許多不同的方法可以實現這一目標。 但是,您可以在彼此之后使用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
來填充NaNs並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,它也是最快的解決方案(至少對於您提供的虛擬數據 - 它可能會針對較大的數據集進行不同的擴展)。
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
您也可以將它們加在一起,因為默認情況下將忽略np.nan
。
df = df.replace("NAN", np.nan). # turn "NAN" to np.nan
df.groupby(["id_1", "id_2"])["value1", "value2"].sum().reset_index()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.