具有以下数据框:
token name ltp change
0 12345.0 abc 2.0 NaN
1 12345.0 abc 5.0 1.500000
2 12345.0 abc 3.0 -0.400000
3 12345.0 abc 9.0 2.000000
4 12345.0 abc 5.0 -0.444444
5 12345.0 abc 16.0 2.200000
6 6789.0 xyz 1.0 NaN
7 6789.0 xyz 5.0 4.000000
8 6789.0 xyz 3.0 -0.400000
9 6789.0 xyz 13.0 3.333333
10 6789.0 xyz 9.0 -0.307692
11 6789.0 xyz 20.0 1.222222
我需要为名称列的每个类别计算正数和负数。在上面的示例
abc:pos_count: 3 abc:neg_count:2
xyz:pos_count:2 xyz:neg_count:2
count=df.groupby('name')['change'].count()
count
但是,这只给了我按组的总数,而不是分别给我的正数和负数。
答案 0 :(得分:1)
将np.sign
与Series.map
一起使用,用于DataFrame.assign
添加的新列,然后按SeriesGroupBy.value_counts
计算值:
count=(df.assign(type=np.sign(df['change'])
.map({1:'pos_count', -1:'neg_count'}))
.groupby(df['name'])['type']
.value_counts()
.reset_index(name='count'))
print (count)
name type count
0 abc pos_count 3
1 abc neg_count 2
2 xyz pos_count 3
3 xyz neg_count 2
答案 1 :(得分:1)
您可以在df
中用符号change
创建新列,并按name
分组并使用符号:
import pandas as pd
import numpy as np
df['change_sign'] = np.sign(df['change'])
df.groupby(['name','change_sign']).count()
然后,如果需要结果以列而不是行为基础,则可以进行透视
答案 2 :(得分:1)
使用:
g = df.groupby('name')['change']
counts = g.agg(
pos_count=lambda s: s.gt(0).sum(),
neg_count=lambda s: s.lt(0).sum(),
net_count=lambda s: s.gt(0).sum()- s.lt(0).sum()).astype(int)
结果:
# print(counts)
pos_count neg_count net_count
name
abc 3 2 1
xyz 3 2 1