[英]Merge two pandas dataframe based on conditional
如果滿足預定條件,則目標是按行合並兩個df
。 具體來說,如果列之間的差異小於或等於threshold
,則加入df
的行。
給定兩個df
:df1 和 df2,以下代碼部分實現了目標。
import pandas as pd
df1 = pd.DataFrame ( {'time': [2, 3, 4, 24, 31]} )
df2 = pd.DataFrame ( {'time': [4.1, 24.7, 31.4, 5]} )
th = 0.9
all_comb=[]
for index, row in df1.iterrows ():
for index2, row2 in df2.iterrows ():
diff = abs ( row ['time'] - row2 ['time'] )
if diff <= th:
all_comb.append({'idx_1':index,'time_1':row ['time'], 'idx_2':index2,'time_2':row2 ['time']})
df_all = pd.DataFrame(all_comb)
輸出
idx_1 time_1 idx_2 time_2
0 2 4 0 4.1
1 3 24 1 24.7
2 4 31 2 31.4
但是,上述方法忽略了某些信息,即來自df1
的 2 和 3 的值,以及來自df2
的 5 的df2
。
預期的輸出應該是這樣的
idx_1 time_1 idx_2 time_2
0 2 NA NA
1 3 NA NA
2 4 0 4.1
3 24 1 24.7
4 31 2 31.4
NA NA 3 5
感謝任何提示或任何比上述建議更緊湊和有效的方式。
您可以執行交叉合並,然后根據您的條件一次對所有行進行子集化。 然后我們concat
,添加回沒有滿足兩個 DataFrame 條件的任何行。
import pandas as pd
df1 = df1.reset_index().add_suffix('_1')
df2 = df2.reset_index().add_suffix('_2')
m = df1.merge(df2, how='cross')
# Subset to all matches: |time_diff| <= thresh
th = 0.9
m = m[(m['time_1'] - m['time_2']).abs().le(th)]
# Add back rows with no matches
res = pd.concat([df1[~df1.index_1.isin(m.index_1)],
m,
df2[~df2.index_2.isin(m.index_2)]], ignore_index=True)
print(res)
index_1 time_1 index_2 time_2
0 0.0 2.0 NaN NaN
1 1.0 3.0 NaN NaN
2 2.0 4.0 0.0 4.1
3 3.0 24.0 1.0 24.7
4 4.0 31.0 2.0 31.4
5 NaN NaN 3.0 5.0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.