python - 避免遍历 Pandas 中的每一行以进行自定义聚合
问题描述
假设我有一个带有两列的 pandas DataFrame:salary
和food_perc
(你花在食物上的工资百分比)。每行对应一个不同的人。
import pandas as pd
import numpy as np
# Set seed
np.random.seed(1)
# Create dataframe
df = pd.DataFrame({'salary': np.round(np.random.uniform(10000, 100000, 100), 2),
'food_perc': np.round(np.random.uniform(0.1, 0.9, 100), 2)})
我想要一个名为food_compare
“每个人在哪里”的新列,我可以看到他们food_perc
与收入相似的人相比如何(+/- 10%)。
因为每个人的 +/- 10% 队列会有所不同,所以我看不出有一种方法可以避免遍历每一行并每次都创建队列,如下所示。
for i in df.index:
# Isolate the cohort
df_sub = df[(df.loc[:, 'salary'] * 0.9 < df.loc[i, 'salary']) &
(df.loc[:, 'salary'] * 1.1 > df.loc[i, 'salary'])]
# Make the comparison
df.loc[i, 'food_compare'] = np.divide(df.loc[i, 'food_perc'],
np.mean(df_sub['food_perc']))
为每次迭代设置数据帧的子集实际上不是一个可扩展的解决方案。不幸的是,我不能为我正在处理的问题预先创建静态箱(例如,10,000-20,000 美元、20,001-30,000 美元等)。
.groupby
当您没有离散键时,有没有办法做某种事情?否则,除了可能事先对行进行排序并修改子集步骤之外,我不确定该怎么做,salary
因此在构建群组时它不会搜索整个数据框。谢谢!
解决方案
要获得每个对等组的计数,您可以使用以下命令:
data['sal_peer_group_count'] = \
data['salary'].apply(lambda x: len(data.loc[(data['salary']>.9*x) & \
(data['salary']<1.1*x)]))
获得对等组平均值sal_perc
data['peer_group_food_perc_mean'] = \
data['salary'].apply(lambda x: data.loc[(data['salary'] >.9*x) & \
(data['salary'] < 1.1*x), 'food_perc'].mean())
请记住,如果您有任何salary
等于零的项目并且您希望它们在同一个组中,则需要将语句修改为:
data['peer_group_food_perc_mean'] = \
data['salary'].apply(lambda x: data.loc[(data['salary'] >.9*x) & \
(data['salary'] < 1.1*x) \
if x != 0 else \
(data['salary'] == 0), 'food_perc'].mean())
推荐阅读
- android - 如何在 android 中将 GDPR 同意传递给 Flurry?
- python - Python Regex:在某些条件下删除数字的替代方法
- linear-regression - lm和dynlm的区别
- rest - REST 客户端扩展未在 VSCode 中发送表单数据
- spring - Maven/Spring/MVC Web 应用程序 - 错误无法 TalendJob(第三方 Talend
- python - 如何正确执行 InstaPy?InstaPy 安装 - Nonebit win 错误
- r - 如何绑定两个具有不同列数的矩阵?
- c# - Kentico CMS 在尝试通过 Kentico API 覆盖现有文件时创建附加文件
- c# - S3 的数据保护密钥环在点网核心中无法正常工作
- python - 控制嵌套列表/字符串的递归(不检查类型)