我正在寻找一个自定义分组函数,该函数将按照以下方式对行进行分组:
举个例子来让事情更清楚:
start_df = pd.DataFrame({"id": [1,1,2,2,3,3,4,4,4,5], "foo": [4, 4, np.nan, 7, np.nan, np.nan, 0, 9, 9, 7], "bar": [np.nan, np.nan, 0, 4, 0, 1, 6, 6, 0, 4]}) id foo bar 0 1 4.0 NaN 1 1 4.0 NaN 2 2 NaN 0.0 3 2 7.0 4.0 4 3 NaN 0.0 5 3 NaN 1.0 6 4 0.0 6.0 7 4 9.0 6.0 8 4 9.0 0.0 9 5 7.0 4.0
自定义 group-by 之后id:
id
result_df = pd.DataFrame({"id": [1,2,3,4,5], "foo": [4, 7, np.nan, 9, 7], "bar": [np.nan, 4, 1, 6, 4]}) id foo bar 0 1 4.0 NaN 1 2 7.0 4.0 2 3 NaN 1.0 3 4 9.0 6.0 4 5 7.0 4.0
我知道的一个解决方案是:
start_df.groupby("id").max().reset_index()
但对于我的情况来说,这太慢了,因为我处理的数据框非常大。另一方面,我无法用这个解决方案覆盖两个元素都是数字的极端情况:
start_df.groupby("id").sum(min_count=1).reset_index()
要实现自定义分组逻辑并确保高效处理大数据集,可以编写一个优化的函数,该函数结合 pandas.groupby 和 apply,通过处理每一组数据时的逻辑操作来实现目标。
pandas.groupby
apply
以下是完整解决方案的代码:
import numpy as np import pandas as pd # 原始数据 start_df = pd.DataFrame({ "id": [1, 1, 2, 2, 3, 3, 4, 4, 4, 5], "foo": [4, 4, np.nan, 7, np.nan, np.nan, 0, 9, 9, 7], "bar": [np.nan, np.nan, 0, 4, 0, 1, 6, 6, 0, 4] }) # 自定义函数,用于处理分组逻辑 def custom_group(series): if series.isna().all(): # 全部是 NaN return np.nan elif (series == 0).any() and series.notna().any(): # 有 0 和其他数字 return series[series != 0].max() else: return series.max() # 返回最大值(自动覆盖数字相等或单个数字的情况) # 按照 'id' 分组,并使用自定义函数应用到每一列 result_df = start_df.groupby("id").agg({ "foo": custom_group, "bar": custom_group }).reset_index() # 输出结果 print(result_df)
id foo bar 0 1 4.0 NaN 1 2 7.0 4.0 2 3 NaN 1.0 3 4 9.0 6.0 4 5 7.0 4.0
series.isna().all()
(series == 0).any()
series.max() 选取组中最大值(已涵盖数字相同的情况)。
series.max()
高效分组:
groupby.agg
自定义函数避免了 max() 和 sum() 的直接限制。
max()
sum()
大数据优化:
groupby