Pandas Groupby:如何使用两个lambda函数?
Pandas Groupby: How to use two lambda functions?
我目前可以在 Pandas 中执行以下操作,但 FutureWarning 严厉批评我:
grpd = df.groupby("rank").agg({
"mean": np.mean, "meian": np.median, "min": np.min, "max": np.max,
"25th percentile": lambda x: np.percentile(x, 25),
"75th percentile": lambda x: np.percentile(x, 75)
})
以下会引发错误,因为我有两个 lambda 函数:
percentile_25 = lambda x: np.percentile(x, 25)
percentile_75 = lambda x: np.percentile(x, 75)
df = diffs[["User Installs", "rank"]].dropna()
grpd = df.groupby("shopping_rank").agg([
np.mean, np.median, np.min, np.max,
percentile_25, percentile_75
])
这抛出:
SpecificationError: Function names must be unique, found multiple named <lambda>
我似乎可以完成这项工作的唯一方法(不忽略警告,我可能应该这样做)是像下面这样的精心设计的过程
- 用一个 lambda 函数(第 25 个百分位数)和我需要的所有其他东西(最小值、最大值等)定义我的 DF
- 重命名列以摆脱 MultiIndex
- 创建另一个 DF,进行另一个分组,这次使用我想要的另一列(第 75 个百分位数)
- 再次重命名 cols(感谢 MultiIndex!)
- 在索引上加入回原来的DF
我在这里遗漏了什么吗?当然有更好的方法来做我认为很常见的事情(使用两个不能直接从 numpy 导入的聚合)。
这是一个known bug,使用:
def percentile_25(x): return np.percentile(x, 25)
def percentile_75(x): return np.percentile(x, 75)
尝试以下小技巧:
percentile_25 = lambda x: np.percentile(x, 25)
percentile_25.__name__ = 'percentile_25'
percentile_75 = lambda x: np.percentile(x, 75)
percentile_75.__name__ = 'percentile_75'
这是另一种类似于 的方法,但是,它允许您创建任意数量的 lambda 函数。所以,如果我们想要每个第 10 个百分位数可以这样做,
n_percentile_groups = 10
lambda_list = []
for pcntl in np.linspace(10, 100, n_percentile_groups):
lmbd = lambda x, pcntl=pcntl: np.percentile(x, int(pcntl))
lmbd.__name__ = 'percentile_%d' % pcntl
lambda_list.append(lmbd)
现在将 lambda_list
传递给 groupby.agg()
或附加其他函数列表,例如 lambda_list + [np.mean, np.min, ...]
.
如果您只想要 5 个不同的百分位数,那么您可以更改 n_percentile_groups = 5
。
最终,我不确定这样做是否是一种稳健或好的方法 - 使用可变数量的 lambdas - 但自从 groupby deprecation - 0.21 这似乎是我知道的唯一方法。非常欢迎对此发表评论。
问题是结果列名称。
备选方案:
percentile_25 = lambda x: np.percentile(x, 25)
percentile_75 = lambda x: np.percentile(x, 75)
grouped = df.groupby("field1")
grouped.agg({
'field2': {'percentile_25': percentile_25, 'percentile_75': percentile_75}
})
我目前可以在 Pandas 中执行以下操作,但 FutureWarning 严厉批评我:
grpd = df.groupby("rank").agg({
"mean": np.mean, "meian": np.median, "min": np.min, "max": np.max,
"25th percentile": lambda x: np.percentile(x, 25),
"75th percentile": lambda x: np.percentile(x, 75)
})
以下会引发错误,因为我有两个 lambda 函数:
percentile_25 = lambda x: np.percentile(x, 25)
percentile_75 = lambda x: np.percentile(x, 75)
df = diffs[["User Installs", "rank"]].dropna()
grpd = df.groupby("shopping_rank").agg([
np.mean, np.median, np.min, np.max,
percentile_25, percentile_75
])
这抛出:
SpecificationError: Function names must be unique, found multiple named <lambda>
我似乎可以完成这项工作的唯一方法(不忽略警告,我可能应该这样做)是像下面这样的精心设计的过程
- 用一个 lambda 函数(第 25 个百分位数)和我需要的所有其他东西(最小值、最大值等)定义我的 DF
- 重命名列以摆脱 MultiIndex
- 创建另一个 DF,进行另一个分组,这次使用我想要的另一列(第 75 个百分位数)
- 再次重命名 cols(感谢 MultiIndex!)
- 在索引上加入回原来的DF
我在这里遗漏了什么吗?当然有更好的方法来做我认为很常见的事情(使用两个不能直接从 numpy 导入的聚合)。
这是一个known bug,使用:
def percentile_25(x): return np.percentile(x, 25)
def percentile_75(x): return np.percentile(x, 75)
尝试以下小技巧:
percentile_25 = lambda x: np.percentile(x, 25)
percentile_25.__name__ = 'percentile_25'
percentile_75 = lambda x: np.percentile(x, 75)
percentile_75.__name__ = 'percentile_75'
这是另一种类似于
n_percentile_groups = 10
lambda_list = []
for pcntl in np.linspace(10, 100, n_percentile_groups):
lmbd = lambda x, pcntl=pcntl: np.percentile(x, int(pcntl))
lmbd.__name__ = 'percentile_%d' % pcntl
lambda_list.append(lmbd)
现在将 lambda_list
传递给 groupby.agg()
或附加其他函数列表,例如 lambda_list + [np.mean, np.min, ...]
.
如果您只想要 5 个不同的百分位数,那么您可以更改 n_percentile_groups = 5
。
最终,我不确定这样做是否是一种稳健或好的方法 - 使用可变数量的 lambdas - 但自从 groupby deprecation - 0.21 这似乎是我知道的唯一方法。非常欢迎对此发表评论。
问题是结果列名称。
备选方案:
percentile_25 = lambda x: np.percentile(x, 25)
percentile_75 = lambda x: np.percentile(x, 75)
grouped = df.groupby("field1")
grouped.agg({
'field2': {'percentile_25': percentile_25, 'percentile_75': percentile_75}
})