sti*_*tes 17 python r pandas data.table
我刚刚从R转换到python,并且在使用R的data.table时再次习惯数据帧时遇到了一些麻烦.我一直遇到的问题是我想要一个字符串列表,检查一个值,然后总结该字符串的数量 - 按用户细分.所以我想拿这个数据:
A_id B C
1: a1 "up" 100
2: a2 "down" 102
3: a3 "up" 100
3: a3 "up" 250
4: a4 "left" 100
5: a5 "right" 102
Run Code Online (Sandbox Code Playgroud)
并返回:
A_id_grouped sum_up sum_down ... over_200_up
1: a1 1 0 ... 0
2: a2 0 1 0
3: a3 2 0 ... 1
4: a4 0 0 0
5: a5 0 0 ... 0
Run Code Online (Sandbox Code Playgroud)
在我使用R代码(使用data.table)之前
>DT[ ,list(A_id_grouped, sum_up = sum(B == "up"),
+ sum_down = sum(B == "down"),
+ ...,
+ over_200_up = sum(up == "up" & < 200), by=list(A)];
Run Code Online (Sandbox Code Playgroud)
但是我最近使用Python的所有尝试都让我失望:
DT.agg({"D": [np.sum(DT[DT["B"]=="up"]),np.sum(DT[DT["B"]=="up"])], ...
"C": np.sum(DT[(DT["B"]=="up") & (DT["C"]>200)])
})
Run Code Online (Sandbox Code Playgroud)
先感谢您!这似乎是一个简单的问题,但我无法在任何地方找到它.
Gar*_*ett 19
为了补充unutbu的答案,这里是一个使用apply
groupby对象的方法.
>>> df.groupby('A_id').apply(lambda x: pd.Series(dict(
sum_up=(x.B == 'up').sum(),
sum_down=(x.B == 'down').sum(),
over_200_up=((x.B == 'up') & (x.C > 200)).sum()
)))
over_200_up sum_down sum_up
A_id
a1 0 0 1
a2 0 1 0
a3 1 0 2
a4 0 0 0
a5 0 0 0
Run Code Online (Sandbox Code Playgroud)
unu*_*tbu 10
可能有更好的方法; 我对熊猫很新,但这很有效:
import pandas as pd
import numpy as np
df = pd.DataFrame({'A_id':'a1 a2 a3 a3 a4 a5'.split(),
'B': 'up down up up left right'.split(),
'C': [100, 102, 100, 250, 100, 102]})
df['D'] = (df['B']=='up') & (df['C'] > 200)
grouped = df.groupby(['A_id'])
def sum_up(grp):
return np.sum(grp=='up')
def sum_down(grp):
return np.sum(grp=='down')
def over_200_up(grp):
return np.sum(grp)
result = grouped.agg({'B': [sum_up, sum_down],
'D': [over_200_up]})
result.columns = [col[1] for col in result.columns]
print(result)
Run Code Online (Sandbox Code Playgroud)
产量
sum_up sum_down over_200_up
A_id
a1 1 0 0
a2 0 1 0
a3 2 0 1
a4 0 0 0
a5 0 0 0
Run Code Online (Sandbox Code Playgroud)
一个老问题;我觉得更好的方法是在分组和聚合之前创建一个新的数据框,并避免应用:
df = df.set_index('A_id')
outcome = {'sum_up' : df.B.eq('up'),
'sum_down': df.B.eq('down'),
'over_200_up' : df.B.eq('up') & df.C.gt(200)}
outcome = pd.DataFrame(outcome).groupby(level=0).sum()
outcome
sum_up sum_down over_200_up
A_id
a1 1 0 0
a2 0 1 0
a3 2 0 1
a4 0 0 0
a5 0 0 0
Run Code Online (Sandbox Code Playgroud)
另一种选择是在分组之前取消堆叠;然而,我觉得这是一个更长、不必要的过程:
(df
.set_index(['A_id', 'B'], append = True)
.C
.unstack('B')
.assign(gt_200 = lambda df: df.up.gt(200))
.groupby(level='A_id')
.agg(sum_up=('up', 'count'),
sum_down =('down', 'count'),
over_200_up = ('gt_200', 'sum')
)
)
sum_up sum_down over_200_up
A_id
a1 1 0 0
a2 0 1 0
a3 2 0 1
a4 0 0 0
a5 0 0 0
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11227 次 |
最近记录: |