(pandas) 根据 groupby 和 column 条件填充 NaN
Posted
技术标签:
【中文标题】(pandas) 根据 groupby 和 column 条件填充 NaN【英文标题】:(pandas) Fill NaN based on groupby and column condition 【发布时间】:2017-06-29 11:15:42 【问题描述】:在 groupby 元素上使用 'bfill' 或 'ffill' 很简单,但是如果您需要根据第三列中的条件在第二列中用特定值填充 na 怎么办?
例如:
>>> df=pd.DataFrame('date':['01/10/2017', '02/09/2017', '02/10/2016','01/10/2017', '01/11/2017', '02/10/2016'], 'a':[1,1,1,2,2,2], 'b':[4,np.nan,6, 5, np.nan, 7])
>>> df
a b date
0 1 4.0 01/10/2017
1 1 NaN 02/09/2017
2 1 6.0 02/10/2016
3 2 5.0 01/10/2017
4 2 NaN 01/11/2017
5 2 7.0 02/10/2016
我需要按“a”列分组,并用“b”列值填充 NaN,其中该行的日期最接近 NaN 行中的日期。
所以输出应该是这样的:
a b date
0 1 4.0 01/10/2017
1 1 6.0 02/09/2017
2 1 6.0 02/10/2016
3 2 5.0 01/10/2017
4 2 5.0 01/11/2017
5 2 7.0 02/10/2016
假设有一个最接近日期() 函数,它获取 NaN 日期和该组中其他日期的列表,并返回最接近的日期。
我正在尝试找到一个无需遍历行的干净解决方案,理想情况下能够将 apply() 与 lambdas 一起使用。有什么想法吗?
【问题讨论】:
您的数据似乎不正确。对于a == 1
组,您选择了6
来填写nan
。但是,01/10/2017
似乎更接近 02/09/2017
,这意味着 4
应该是填充值。
【参考方案1】:
这应该可行:
df['closest_date_by_a'] = df.groupby('a')['date'].apply(closest_date)
df['b'] = df.groupby(['a', 'closest_date_by_a'])['b'].ffill().bfill()
给定一个函数 (closest_date()
),您需要按组应用该函数,以便计算每个组中行的最接近日期。然后您可以按主分组列 (a
) 和最近的日期列 (closest_date_by_a
) 进行分组并执行填充。
【讨论】:
【参考方案2】:确保您的 date
列实际上是日期。
df = pd.DataFrame(
'date': ['01/10/2017', '02/09/2017', '02/10/2016','01/10/2017', '01/11/2017', '02/10/2016'],
'a':[1,1,1,2,2,2], 'b':[4,np.nan,6, 5, np.nan, 7])
df.date = pd.to_datetime(df.date)
print(df)
a b date
0 1 4.0 2017-01-10
1 1 NaN 2017-02-09
2 1 6.0 2016-02-10
3 2 5.0 2017-01-10
4 2 NaN 2017-01-11
5 2 7.0 2016-02-10
在拥有dropna()
之后使用reindex
和method='nearest'
def fill_with_nearest(df):
s = df.set_index('date').b
s = s.dropna().reindex(s.index, method='nearest')
s.index = df.index
return s
df.loc[df.b.isnull(), 'b'] = df.groupby('a').apply(fill_with_nearest).reset_index(0, drop=True)
print(df)
a b date
0 1 4.0 2017-01-10
1 1 4.0 2017-02-09
2 1 6.0 2016-02-10
3 2 5.0 2017-01-10
4 2 5.0 2017-01-11
5 2 7.0 2016-02-10
【讨论】:
感谢您的回答。我不知道“最近的”填充方法,这很整洁。我正在对我的数据尝试这种方法,它适用于几次迭代然后给出一个错误:ValueError: cannot reindex a non-unique index with a method or limit
知道什么会导致这种情况吗?我试图通过添加具有相同“日期”值的新行来重新创建示例中的错误,但它仍然可以正常工作。以上是关于(pandas) 根据 groupby 和 column 条件填充 NaN的主要内容,如果未能解决你的问题,请参考以下文章
Pandas - dataframe groupby - 如何获得多列的总和
Pandas 的 [df.groupby(...)['col_name'].shift(1)] 的 SQL 等效项