我对标准化分组数据框中的计数有疑问。
我的数据如下:
import pandas as pd
data = [{'system': 'S1', 'id': '1', 'output': ['apple', 'pear']},
{'system': 'S1', 'id': '2', 'output': []},
{'system': 'S1', 'id': '3', 'output': []},
{'system': 'S2', 'id': '4', 'output': ['apple', 'grape']},
{'system': 'S2', 'id': '5', 'output': ['apple']}]
df = pd.DataFrame(data)
以表格格式显示如下:
system id output
0 S1 1 [apple, pear]
1 S1 2 []
2 S1 3 []
3 S2 4 [apple, grape]
4 S2 5 [apple]
如何获得每个系统每个输出的归一化计数?
它应该像这样:
system output perc
S1 apple 0.33
S1 pear 0.33
S2 apple 1.0
S2 grape 0.5
意味着apple
和pear
出现在所有S1
输出的三分之一中,apple
出现在所有S2
输出中,grape
出现S2
输出的一半。
我试图爆炸每个系统的输出并获得每个系统ID的单独计数,但是合并它们会丢失output
列:
outputs = df.explode('output').groupby(['system', 'output']).count()
counts = df.groupby('system').agg('count').id
pd.merge(outputs, counts, on="system")
答案 0 :(得分:1)
对于0.25+的熊猫,我们可以使用explode
:
(df.explode('output')
.groupby('system')
.apply(lambda x:x['output'].value_counts()/x['id'].nunique())
.reset_index()
)
输出:
system level_1 output
0 S1 pear 0.333333
1 S1 apple 0.333333
2 S2 apple 1.000000
3 S2 grape 0.500000
答案 1 :(得分:1)
IIUC,SeriesGroupBy.value_counts()
与Serives.value_counts()
和Series.map()
new_df = (df.explode('output').groupby('system')['output'].value_counts()
.reset_index(name='perc')
.assign(perc=lambda x: x['perc'].div(x['system']\
.map(df['system'].value_counts()))))
print(new_df)
system output perc
0 S1 apple 0.333333
1 S1 pear 0.333333
2 S2 apple 1.000000
3 S2 grape 0.500000
示例数据框的时间
%%timeit
new_df = (df.explode('output').groupby('system')['output'].value_counts()
.reset_index(name='perc')
.assign(perc=lambda x: x['perc'].div(x['system']\
.map(df['system'].value_counts()))))
9.19 ms ± 64.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
(df.explode('output')
.groupby('system')
.apply(lambda x:x['output'].value_counts()/x['id'].nunique())
.reset_index()
)
12.3 ms ± 134 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)