时间序列:从另一个数据框中填充 NaN

Time Series: Fill NaNs from another dataframe

我正在处理温度数据,我创建了一个文件,其中包含几千个城市的多年平均值,格式如下(df1)

Date    City    PRCP    TMAX    TMIN    TAVG
01-Jan  Zurich  0.94    3.54    0.36    1.95
01-Feb  Zurich  4.12    9.14    3.04    6.09
01-Mar  Zurich  4.1     5.9     0.3     3.1
01-Apr  Zurich  0.32    13.78   4.22    9
01-May  Zurich  9.42    11.32   5.34    8.33
.
.
.....

我有所有 365 天的上述数据,没有空值。请注意,date 列只有 daymonth,因为年份不相关。

根据以上数据,我正在尝试清理年度文件,我的第二个数据框包含以下格式的数据(df2)

ID      Date        City    PRCP    TAVG    TMAX    TMIN
abcd1   2020-01-01  Zurich  0       -1.9    -0.9    
abcd1   2020-01-02  Zurich  9.1             12.7    4.9
abcd1   2020-01-03  Zurich  0.8      8.55   13.2    3.9
abcd1   2020-01-04  Zurich  0        4.1    10.8    -2.6

.
.
.....

每个城市都有一个独特的ID。日期列的格式为 %y-%m-%d.

我正在尝试通过匹配 daymonth 将第二个数据框中的空值替换为第一个数据框中的值。这是我试过的

df1["Date"] = pd.to_datetime(df1["Date"], errors = 'coerce')   ##date format change##
df1["Date"] = df1['Date'].dt.strftime('%d-%m')
df2 = df2.drop(columns='ID')

df2 = df2.fillna(df1)         ##To replace nulls##

df1["Date"] = pd.to_datetime(df1["Date"], errors = 'coerce')
df1["Date"] = df1['Date'].dt.strftime('%Y-%m-%d')      ## Change data back to original format##

即便如此,我的年度文件中仍然有空值,即 df2{注意:df1 没有空值}

如有必要,请提出一个更好的方法来仅替换空值或对代码进行任何更正。

我们可以通过在 df2 上添加一列 Date2,其格式与 df1 上的 Date 列相同。然后,在使用此日期格式和城市作为索引设置两个数据框的同时,我们使用 .update() 对 df2 执行更新,如下所示:

df2["Date2"] = pd.to_datetime(df2["Date"], errors = 'coerce').dt.strftime('%d-%b')          #  dd-MMM (e.g. 01-JAN)

df2a = df2.set_index(['Date2', 'City'])        # Create df2a from df2 with set index on Date2 and City

df2a.update(df1.set_index(['Date', 'City']), overwrite=False)   # update only NaN values of df2a by corresponding values of df1

df2 = df2a.reset_index(level=1).reset_index(drop=True)    # result put back to df2 throwing away the temp `Date2` row index

df2.insert(2, 'City', df2.pop('City'))    # relocate column City back to its original position

.update() 是使用来自另一个 DataFrame 的非 NA 值进行就地修改。 DataFrame 的长度不会因为更新而增加,只会更新匹配 index/column 标签处的值。因此,我们使两个数据帧都具有相同的行索引,以便对具有相同列 index/labels.

的相应列执行更新

请注意,我们在 .update() 中使用参数 overwrite=False 来确保我们仅更新原始 DataFrame df2.

中为 NaN 的值

演示

数据设置:

将数据添加到 df1 以展示 df2df1:

的替换值
print(df1)

     Date    City  PRCP   TMAX  TMIN  TAVG
0  01-Jan  Zurich  0.94   3.54  0.36  1.95
1  02-Jan  Zurich  0.95   3.55  0.37  1.96       <=== Added this row
2  01-Feb  Zurich  4.12   9.14  3.04  6.09
3  01-Mar  Zurich  4.10   5.90  0.30  3.10
4  01-Apr  Zurich  0.32  13.78  4.22  9.00
5  01-May  Zurich  9.42  11.32  5.34  8.33

print(df2)       #  before processing

      ID        Date    City  PRCP  TAVG  TMAX  TMIN
0  abcd1  2020-01-01  Zurich   0.0 -1.90  -0.9   NaN         <=== with NaN value
1  abcd1  2020-01-02  Zurich   9.1   NaN  12.7   4.9         <=== with NaN value
2  abcd1  2020-01-03  Zurich   0.8  8.55  13.2   3.9
3  abcd1  2020-01-04  Zurich   0.0  4.10  10.8  -2.6

运行 新代码:

df2["Date2"] = pd.to_datetime(df2["Date"], errors = 'coerce').dt.strftime('%d-%b')          #  dd-MMM (e.g. 01-JAN)

df2a = df2.set_index(['Date2', 'City'])        # Create df2a from df2 with set index on Date2 and City

df2a.update(df1.set_index(['Date', 'City']), overwrite=False)   # update only NaN values of df2a by corresponding values of df1

df2 = df2a.reset_index(level=1).reset_index(drop=True)    # result put back to df2 throwing away the temp `Date2` row index

df2.insert(2, 'City', df2.pop('City'))    # relocate column City back to its original position

结果:

print(df2)


      ID       Date    City  PRCP  TAVG  TMAX  TMIN
0  abcd1 2020-01-01  Zurich   0.0 -1.90  -0.9  0.36     <== TMIN updated with df1 value
1  abcd1 2020-01-02  Zurich   9.1  1.96  12.7  4.90     <== TAVG updated with df1 value
2  abcd1 2020-01-03  Zurich   0.8  8.55  13.2  3.90
3  abcd1 2020-01-04  Zurich   0.0  4.10  10.8 -2.60