在公共值上连接数据帧会产生不匹配的 NaN 值 [python]

Concatenate Dataframes on common values yields NaN values for non-matches [python]

我正在尝试 merge/concatenate 公共列上的两个数据框并匹配所有相应的值。但是,当匹配值接收该行的相应值时,如果没有匹配项,则会生成 NaN 值。我为此使用 python。我会在这里更详细地解释。

我有这个数据框 A:

      ID     Area    Distance     Height       Temp
----------------------------------------------------
0    100     8.31           0       1.30      24.27
1    101     3.11           0       1.29      25.99
2    102     5.10           0       1.23      29.51
3    105     9.70           0       1.97      15.17
4    107     4.77           0       1.53      27.84
...

每个 ID 代表一个不同的建筑物足迹(多边形),记录了它的面积、建筑物的高度以及建筑物所在位置记录的室外平均温度。 “距离”列表示距离记录温度的建筑物的距离,因此现场 = 0 米远。

我有这个数据框 B:

        ID      Temp    Distance
---------------------------------
 0     100     25.68           5
 1     100     26.05          10
 2     100     26.85          15
 3     100     27.25          20
 4     100     27.78          25
 5     101     22.68           5
 6     101     26.44          10
 7     101     26.83          15
 8     101     27.26          20
 9     101     28.38          25
10     102     25.63           5
11     102     26.26          10
12     102     26.57          15
13     102     26.91          20
14     102     28.84          25
15     105     25.33           5
16     105     26.25          10
17     105     26.54          15
18     105     26.23          20
19     105     27.53          25
20     107     25.23           5
21     107     26.73          10
22     107     26.26          15
23     107     26.11          20
24     107     27.16          25
...

这显示了同一建筑物 ID 在距建筑物不同距离处记录的温度,因此对于每栋建筑物,我想要记录的平均室外温度分别为 5 米、10 米、15 米、20 米, 距离25米。

我想做的是通过公共“ID”列连接数据帧 A 和 B。所以我想做的是生成一个数据框 C,它为每个 ID 显示距离为 0、5、10、15、20 和 25 的建筑物温度。问题是我希望每个建筑物 ID 的面积和高度为保持不变,因为建筑物的面积和高度当然不会改变!所以我想生成以下数据框 C:

       ID     Area    Distance     Height       Temp
----------------------------------------------------
 0    100     8.31           0       1.30      24.27
 1    100     8.31           5       1.30      25.68
 2    100     8.31          10       1.30      26.05
 3    100     8.31          15       1.30      26.85    
 4    100     8.31          20       1.30      27.25    
 5    100     8.31          25       1.30      27.78
 6    101     3.11           0       1.29      25.99
 7    101     3.11           5       1.29      22.68    
 8    101     3.11          10       1.29      26.44    
 9    101     3.11          15       1.29      26.83    
10    101     3.11          20       1.29      27.26    
11    101     3.11          25       1.29      28.38    
12    102     5.10           0       1.23      29.51
13    102     5.10           5       1.23      25.63    
14    102     5.10          10       1.23      26.26    
15    102     5.10          15       1.23      26.57    
16    102     5.10          20       1.23      26.91     
17    102     5.10          25       1.23      28.84
18    105     9.70           0       1.97      15.17
19    105     9.70           5       1.97      25.33
20    105     9.70          10       1.97      26.25
21    105     9.70          15       1.97      26.54
22    105     9.70          20       1.97      26.23
23    105     9.70          25       1.97      27.53
24    107     4.77           0       1.53      27.84
25    107     4.77           5       1.53      25.23
26    107     4.77          10       1.53      26.73
27    107     4.77          15       1.53      26.26
28    107     4.77          20       1.53      26.11
29    107     4.77          25       1.53      27.16
...

因此,为了获得这一点,我尝试了以下操作,尝试在“ID”列上连接数据帧 A 和 B,然后按“ID”和“距离”对行进行排序:

df_C =  pd.concat([df_A, df_B]).sort_values(["ID", "Distance"]).reset_index(drop=True)

然而这会产生:

       ID     Area    Distance     Height       Temp
----------------------------------------------------
 0    100     8.31           0       1.30      24.27
 1    100      NaN           5        NaN      25.68
 2    100      NaN          10        NaN      26.05
 3    100      NaN          15        NaN      26.85    
 4    100      NaN          20        NaN      27.25    
 5    100      NaN          25        NaN      27.78
 6    101     3.11           0       1.29      25.99
 7    101      NaN           5        NaN      22.68    
 8    101      NaN          10        NaN      26.44    
 9    101      NaN          15        NaN      26.83    
10    101      NaN          20        NaN      27.26    
11    101      NaN          25        NaN      28.38    
12    102     5.10           0       1.23      29.51
13    102      NaN           5        NaN      25.63    
14    102      NaN          10        NaN      26.26    
15    102      NaN          15        NaN      26.57    
16    102      NaN          20        NaN      26.91     
17    102      NaN          25        NaN      28.84
18    105     9.70           0        1.97     15.17
19    105      NaN           5        NaN      25.33
20    105      NaN          10        NaN      26.25
21    105      NaN          15        NaN      26.54
22    105      NaN          20        NaN      26.23
23    105      NaN          25        NaN      27.53
24    107     4.77           0       1.53      27.84
25    107      NaN           5        NaN      25.23
26    107      NaN          10        NaN      26.73
27    107      NaN          15        NaN      26.26
28    107      NaN          20        NaN      26.11
29    107      NaN          25        NaN      27.16
...

因此,Area 和 Height 值似乎没有匹配,因为 Dataframe B 不包含相应的 Area 和 Height 值,因此当我合并这两个 DataFrame 时,那里没有任何可报告的内容。我该如何解决这个问题,以便获得我想要的 Dataframe C?

如果您确定所有 ID 都在 df_A 中并且距离为 0,并且除了面积和高度中没有其他 nan,那么使用 ffill 可以按照您的方式进行一次排序做了。

df_C = df_C.ffill()

如果你不确定,那么你可以先用groupby.transform然后用fillna

df_C = df_C.fillna(df_C.groupby('ID')[['Area', 'Height']].transform('first'))

最后,另一种选择是先在df_B中添加列Area和Height,然后concat so:

df_C =  pd.concat([
    df_A, 
    df_B.merge(df_A[['ID','Area','Height']], on='ID', how='left')]
).sort_values(["ID", "Distance"]).reset_index(drop=True)