簡體   English   中英

合並兩個具有匹配 ID 的不同長度的數據幀,並在兩列上填充主要 dataframe 的 NaN 值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM