【问题标题】:How to fill NaN values based on previous columns如何根据以前的列填充 NaN 值
【发布时间】:2020-02-12 11:43:57
【问题描述】:

我有一个没有缺失数据 (A) 但具有重复值的初始列。如何用缺失的数据填充下一列 (B) 以便填充并且左侧的列在右侧始终具有相同的值?我还希望任何其他列保持不变(C)

例如,这就是我所拥有的

    A    B     C
1   1    20    4
2   2    NaN   8
3   3    NaN   2
4   2    30    9
5   3    40    1
6   1    NaN   3

这就是我想要的

    A    B     C
1   1    20    4
2   2    30*   8
3   3    40*   2
4   2    30    9
5   3    40    1
6   1    20*   3

填充值上的星号。

这需要使用非常大的数据框进行扩展。

另外,如果我在左列有一个值,而在单独的观察中右侧有多个值,我将如何填充平均值?

【问题讨论】:

  • 答案很复杂。假设您有大量数据,那么插补取决于数据的类型。虽然,这可以通过编程方式完成,但在此之前您需要对数据进行预分析并检查各种类型的缺失。不需要所有数据。
  • 你想要:df['B'] = df['B'].fillna(df.groupby('A')['B'].transform('mean')) 之前有人问过类似的问题,我在这里解释了如何用组的平均值填充缺失的数字:stackoverflow.com/questions/60192232/…

标签: python pandas dataframe


【解决方案1】:

您可以在'A' 上使用groupby 并使用first 查找'B' 中的第一个对应值(不会选择NaN)。

import pandas as pd

df = pd.DataFrame({'A':[1,2,3,2,3,1], 
                   'B':[20, None, None, 30, 40, None], 
                   'C': [4,8,2,9,1,3]})

# find first 'B' value for each 'A'
lookup = df[['A', 'B']].groupby('A').first()['B']

# only use rows where 'B' is NaN
nan_mask = df['B'].isnull()

# replace NaN values in 'B' with lookup values
df['B'].loc[nan_mask] = df.loc[nan_mask].apply(lambda x: lookup[x['A']], axis=1)

print(df)

哪些输出:

   A     B  C
0  1  20.0  4
1  2  30.0  8
2  3  40.0  2
3  2  30.0  9
4  3  40.0  1
5  1  20.0  3

如果'B' 中有许多NaN 值,您可能需要在使用groupby 之前排除它们。

import pandas as pd

df = pd.DataFrame({'A':[1,2,3,2,3,1], 
                   'B':[20, None, None, 30, 40, None], 
                   'C': [4,8,2,9,1,3]})

# Only use rows where 'B' is NaN
nan_mask = df['B'].isnull()

# Find first 'B' value for each 'A'
lookup = df[~nan_mask][['A', 'B']].groupby('A').first()['B']

df['B'].loc[nan_mask] = df.loc[nan_mask].apply(lambda x: lookup[x['A']], axis=1)

print(df)

【讨论】:

    【解决方案2】:

    您可以先执行 sort_values,然后根据 A 列向前填充 B 列。实现此的方法是:

    import pandas as pd
    import numpy as np
    
    x = {'A':[1,2,3,2,3,1],
         'B':[20,np.nan,np.nan,30,40,np.nan],
         'C':[4,8,2,9,1,3]}
    
    df = pd.DataFrame(x)
    
    #sort_values first, then forward fill based on column B
    #this will get the right values for you while maintaing
    #the original order of the dataframe
    df['B'] = df.sort_values(by=['A','B'])['B'].ffill()
    print (df)
    

    输出将是:

    原始数据:

       A     B  C
    0  1  20.0  4
    1  2   NaN  8
    2  3   NaN  2
    3  2  30.0  9
    4  3  40.0  1
    5  1   NaN  3
    

    更新数据:

       A     B  C
    0  1  20.0  4
    1  2  30.0  8
    2  3  40.0  2
    3  2  30.0  9
    4  3  40.0  1
    5  1  20.0  3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-24
      • 2017-10-07
      • 2015-10-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 2019-11-21
      • 2021-01-20
      相关资源
      最近更新 更多