【问题标题】:Replacing missing values in a Pandas DataFrame based on values in another Pandas DataFrame根据另一个 Pandas DataFrame 中的值替换 Pandas DataFrame 中的缺失值
【发布时间】:2021-10-30 01:51:37
【问题描述】:

我需要使用来自另一个 DataFrame 的值替换 Pandas DataFrame 中的缺失值。

df1 = pd.DataFrame({'ID':['1111','2222','3333','4444','5555'],'Test':['T1','T1','T1','T2','T2'], 'Day1': ['P','P','P','P','P'], 'Day2': ['P','P','P','P', 'NaN'], 'Day3':['P','P','NaN','P','NaN'], 'Day4': ['P','P','NaN','P','NaN']})
    ID   Test Day1 Day2 Day3 Day4
0   1111 T1   P    P    P    P
1   2222 T1   P    P    P    P
2   3333 T1   P    P    NaN  NaN
3   4444 T2   P    P    P    P
4   5555 T2   P    NaN  NaN  NaN

df2 = pd.DataFrame({'ID':['3333','5555'], 'Test':['T1','T2'], 'Label': ['OOT-P', 'OOT-T']})
    ID   Test Label
0   3333 T1   OOT-P
1   5555 T2   OOT-T

需要将 df1 中第 3 天和第 4 天 ID=3333 和 test=T1 的 NaN 替换为 df2 中的 OOT-P。

需要将 df1 中第 2 天、第 3 天、第 4 天 ID=5555 和 test=T2 的 NaN 替换为 df2 中的 OOT-T。

两个数据框都将始终具有 ID 和 Test 列,但 df1 中其他列的名称和数量会发生变化。例如,df1 可能有 Day1、Day2、Day3、Day4、Day5 列或 Week1、Week2、Week3 列。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以在df1 中将df2 重塑为fillna

    需要做一些事情:将字符串 'NaN' 替换为实际浮点数 NaN,临时将 ID/Test 设置为索引,并临时转置数据帧(fillna 与 Series/dictionary 仅适用于列)

    (df1.replace('NaN', float('nan'))
        .set_index(['ID','Test']).T
        .fillna(df2.set_index(['ID','Test'])['Label'])
        .T.reset_index()
     )
    

    输出:

         ID Test Day1   Day2   Day3   Day4
    0  1111   T1    P      P      P      P
    1  2222   T1    P      P      P      P
    2  3333   T1    P      P  OOT-P  OOT-P
    3  4444   T2    P      P      P      P
    4  5555   T2    P  OOT-T  OOT-T  OOT-T
    

    【讨论】:

    • 这是一个更优雅的解决方案
    【解决方案2】:

    您还可以创建一个元组列表,其中包含您想要更改的 ID 以及您想要将它们更改为的值。然后,您可以简单地遍历 ID 并将 NaN 值替换为您的新值。

    IDS_to_Change = df2.ID.values.tolist()
    
    New_Vals = []
    for i in range(len(df2.index)):
        New_Vals.append(df2[df2['ID'] == IDS_to_Change[i]].Label[i])
    
    Data_to_Merge = list(zip(IDS_to_Change, New_Vals))
    
    for ids in Data_to_Merge:
        for i in range (len(df1.index)):
            if df1['ID'][i] == ids[0]:
                id_name = ids[0]          
                index = df1[df1['ID'] == id_name].index[0]
                for j in range(len(df1[df1['ID'] == id_name].columns)):
                     if df1[df1['ID'] == id_name].loc[index][j] == 'NaN':
                        df1.iloc[index][j] = ids[1]
    

    输出:

        ID    Test  Day1    Day2    Day3    Day4
    0   1111    T1     P       P       P       P
    1   2222    T1     P       P       P       P
    2   3333    T1     P       P   OOT-P   OOT-P
    3   4444    T2     P       P       P       P
    4   5555    T2     P   OOT-T   OOT-T   OOT-T
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 2018-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-15
      • 2019-07-16
      相关资源
      最近更新 更多