我正在处理一个大型案例级数据集,并且对 python 是全新的。数据集通常看起来像这样:
Site Type Value
A Red 10
A Blue 15
B Red 35
B Yellow 5
C Blue 45
C Red 25
我正在尝试使用 python 自动化我们的一些流程,其中涉及聚合数据并按站点对其进行分组。我需要的输出如下所示:
Site RedType BlueType YellowType Value0-20 Value20-40 Value40+
A 1 1 0 2 0 0
B 1 0 1 1 1 0
C 1 1 0 0 1 1
基于我对到目前为止所做的事情的有限理解,我相信我偶然发现的解决方案是为我需要的每一列创建一个包含字段的字典,并将其应用为按站点分组的一部分:
def my_agg(data):
names = {
'RedType': data[data['Type']=="Red"]['Id'].count(),
'BlueType': data[data['Type']=="Blue"]['Id'].count(),
'YellowType':data[data['Type']=="Yellow"]['Id'].count(),
'Value0-20': data[data['Value']>=0]['Id'].count() and data[data['Value']<=20]['Id'].count()
etc........
return pd.Series(names)
df = data.groupby('Site').apply(my_agg)
我现在知道 and 运算符不适用于值字段,但到目前为止其余操作符都有效。有没有办法使用此方法有条件地计算值(计算两个不同值之间的每种情况)?不管怎样,我是否忽略了我可以这样做的其他方式?
cut
计算值的 bin,然后使用 melt
类型/值列,最后使用 crosstab
进行计数并展平 MultiIndex:
tmp = (df.assign(Value=lambda d: pd.cut(d['Value'],
bins=[0, 20, 40, np.inf],
labels=['0-20', '20-40', '40+']))
.melt('Site')
)
out = pd.crosstab(tmp['Site'], [tmp['variable'], tmp['value']])
out.columns = out.columns.map(lambda x: f'{x[0]}_{x[1]}')
out = out.reset_index()
concat
:
index = 'Site'
# the following command modifies the original input in place
df['Value'] = pd.cut(df['Value'],
bins=[0, 20, 40, np.inf],
labels=['0-20', '20-40', '40+'])
out = pd.concat([pd.crosstab(df[index], df[col]).add_prefix(f'{col}_')
for col in df.columns.difference([index])],
axis=1).reset_index()
输出:
Site Type_Blue Type_Red Type_Yellow Value_0-20 Value_20-40 Value_40+
0 A 1 1 0 2 0 0
1 B 0 1 1 1 1 0
2 C 1 1 0 0 1 1