[英]Merge two dataframes of different lengths with matching ID and fill NaN values of main dataframe on two columns
我有兩個數據框,主要的 dataframe 有兩列 Lat 和 Long,其中一些有值,一些是 NaN。 我有另一個 dataframe,它是這個主要的 dataframe 的子集,其中 Lat 和 Long 填充了值。 我想根據匹配 ID 將這些值填充到主 DataFrame 中。
總機 DataFrame:
ID Lat Long
0 9547507704 33.853682 -80.369867
1 9777677704 32.942332 -80.066165
2 5791407702 47.636067 -122.302559
3 6223567700 34.224719 -117.372550
4 9662437702 42.521828 -82.913680
... ... ... ...
968552 4395967002 NaN NaN
968553 6985647108 NaN NaN
968554 7996438405 NaN NaN
968555 9054647103 NaN NaN
968556 9184687004 NaN NaN
DataFrame 填寫:
ID Lat Long
0 2392497107 36.824257 -76.272486
1 2649457102 37.633918 -77.507746
2 2952437110 37.511077 -77.528711
3 3379937304 39.119430 -77.569008
4 3773127208 36.909731 -76.070420
... ... ... ...
23263 9512327001 37.371059 -79.194838
23264 9677417002 38.406665 -78.913133
23265 9715167306 38.761194 -77.454184
23266 9767568404 37.022287 -76.319882
23267 9872047407 38.823017 -77.057818
這兩個數據幀的長度不同。
編輯澄清:如果 ID 在兩個 DataFrame 中匹配,我需要用子集中的緯度和經度替換主要 DataFrame 的緯度和經度列中的 NaN。 我的 DataFrame 都是 >60 列,我只是想為這兩列替換 NaN。
編輯:
我選擇了這個映射解決方案,雖然它不是我正在尋找的,但我知道有一個更簡單的解決方案。
#mapping coordinates to NaN values in main
m = dict(zip(fill_df.ID,fill_df.Lat))
main_df.Lat = main_df.Lat.fillna(main_df.ID.map(m))
n = dict(zip(fill_df.ID,fill_df.Long))
main_df.Long = main_df.Long.fillna(main_df.ID.map(n))
new_df = pd.merge(main_df, sub_df, how='left', on='ID')
我想左連接會完成這項工作。
一種方法是使用DataFrame.combine_first
。 該方法在索引和列上對齊 DataFrame,因此您需要將ID
設置為每個 DataFrame 的索引,調用df_main.combine_first(df_filler)
,然后將ID
重置為列。 (看起來很尷尬;可能有更優雅的方法。)
假設您的主要 DataFrame 被命名為df_main
並且您要填充的 DataFrame 被命名為df_filler
:
df_main.set_index('ID').combine_first(df_filler.set_index('ID')).reset_index()
這應該可以解決問題:
import math
A = pd.DataFrame({'ID' : [1, 2, 3], 'Lat':[4, 5, 6], 'Long': [7, 8, float('nan')]})
B = pd.DataFrame({'ID' : [2, 3], 'Lat':[5, 6], 'Long': [8, 9]})
print('Old table:')
print(A)
print('Fix table:')
print(B)
for i in A.index.to_list():
for j in B.index.to_list():
if not A['ID'][i] == B['ID'][j]:
continue
if math.isnan(A['Lat'][i]):
A.at[i, 'Lat'] = B['Lat'][j]
if math.isnan(A['Long'][i]):
A.at[i, 'Long'] = B['Long'][j]
print('New table:')
print(A)
回報:
ID Lat Long
0 1 4 7.0
1 2 5 8.0
2 3 6 NaN
Fix table:
ID Lat Long
0 2 5 8
1 3 6 9
New table:
ID Lat Long
0 1 4 7.0
1 2 5 8.0
2 3 6 9.0
不是很優雅,但可以完成工作:)
A.set_index('ID').fillna(B[['ID', 'Lat', 'Long']].set_index('ID')).reset_index()
例子:
>>> A
ID Lat Long Dont Update
0 1 4 7.0 7.0
1 2 5 8.0 8.0
2 3 6 NaN NaN
>>> B
ID Lat Long Dont Update
0 2 5 8 10
1 3 6 9 10
>>> A.set_index('ID').fillna(B[['ID', 'Lat', 'Long']].set_index('ID')).reset_index()
ID Lat Long Dont Update
0 1 4 7.0 7.0
1 2 5 8.0 8.0
2 3 6 9.0 NaN
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.