Pandas groupby 常用功能
示例DataFrame
key | value |
---|
A | 10 |
A | 30 |
A | 20 |
B | 33 |
B | 22 |
B | 11 |
【sum】key内部求value的和
gp = data.groupby(["key"])["value"].sum().reset_index()
gp.rename(columns={"value":"sum_of_value"},inplace=True)
index | key | sum_of_value |
---|
0 | A | 60 |
1 | B | 66 |
【cumsum】key内部value的累计和
gp = data.groupby(["key"])["value"].cumsum().reset_index()
gp.rename(columns={"value":"cumsum_of_value"},inplace=True)
index | rank_of_value |
---|
0 | 10 |
1 | 40 |
2 | 60 |
3 | 33 |
4 | 55 |
5 | 66 |
【prod】key内部求value的积
gp = data.groupby(["key"])["value"].prod().reset_index()
gp.rename(columns={"value":"prod_of_value"},inplace=True)
index | key | sum_of_value |
---|
0 | A | 6000 |
1 | B | 7986 |
【mean】key内部求value的均值
gp = data.groupby(["key"])["value"].mean().reset_index()
gp.rename(columns={"value":"mean_of_value"},inplace=True)
index | key | mean_of_value |
---|
0 | A | 20 |
1 | B | 22 |
【max】key内部求value最大值
gp = data.groupby(["key"])["value"].max().reset_index()
gp.rename(columns={"value":"max_of_value"},inplace=True)
index | key | max_of_value |
---|
0 | A | 30 |
1 | B | 33 |
【min】key内部求value最小值
gp = data.groupby(["key"])["value"].min().reset_index()
gp.rename(columns={"value":"min_of_value"},inplace=True)
index | key | min_of_value |
---|
0 | A | 10 |
1 | B | 11 |
【idxmax】key内部value的最大值的index
注意,这里的index是原DataFrame中的index,例如A中value的最大值30的index在整个DataFrame中是1,而B中value的最大值33的index在整个DataFrame中是3。
gp = data.groupby(["key"])["value"].idxmax().reset_index()
gp.rename(columns={"value":"maxidx_of_value"},inplace=True)
index | key | maxidx_of_value |
---|
0 | A | 1 |
1 | B | 3 |
【rank】key内部value的排名
目前的尝试,rank返回的DataFrame长度等于原长,排列顺序与原DataFrame一致。
gp = data.groupby(["key"])["value"].rank().reset_index()
gp.rename(columns={"value":"rank_of_value"},inplace=True)
index | rank_of_value |
---|
0 | 1.0 |
1 | 3.0 |
2 | 2.0 |
3 | 3.0 |
4 | 2.0 |
5 | 1.0 |
如果value有同值,例如将A中第二行的30改成20,rank会出现小数。
index | rank_of_value |
---|
0 | 1.0 |
1 | 2.5 |
2 | 2.5 |
3 | 3.0 |
4 | 2.0 |
5 | 1.0 |
常见特征提取
key每天的样本总量
用size可以实现统计“用户每天搜索次数”这样的特征,例如下面这个DataFrame,用户A在第1天和第二天的搜索次数(样本量)分别是1次和2次,用户B则在第一天搜索2次。
gp = data.groupby(["user_id","day"]).size().reset_index()
gp.rename(columns={0:"count"},inplace=True)
index | user_id | day | count |
---|
0 | A | 1 | 1 |
1 | A | 2 | 2 |
2 | B | 1 | 2 |
key每天取value的次数
同样,用size可以实现“用户每天搜索某品牌brand的次数(样本量)”之类的特征,只需要改变groupby中的内容即可。例如下面这个DataFrame,用户A在第1天搜索X2次,搜索Y1次,第2天搜索X1次。值得注意的是,如果没有发生过搜索,是不会显示出来的,例如“第2天搜索Y0次”是不会出现在结果中的。
user_id | brand_id | day |
---|
A | X | 1 |
A | X | 1 |
A | X | 2 |
A | Y | 1 |
gp = data.groupby(["user_id","brand_id","day"]).size().reset_index()
gp.rename(columns={0:"count"},inplace=True)
index | user_id | brand_id | day | count |
---|
0 | A | X | 1 | 2 |
1 | A | X | 2 | 1 |
2 | A | Y | 1 | 1 |
key在当天以前的访问次数总量
可以利用size和cumsum实现历史统计量,类似“用户在当天以前搜索某个品牌的总次数(不包括当天)”,基本思路是先用size统计每天关于该品牌的次数统计,然后用它做cumsum,就得到了包括当天的历史总次数,最后减去每天的次数统计即可。
user_id | brand_id | day |
---|
A | X | 1 |
A | X | 2 |
A | X | 2 |
A | X | 3 |
A | X | 4 |
gp = data.groupby(["user_id","brand_id","day"]).size().reset_index()
gp.rename(columns={0:"count"}, inplace=True)
gp["cum_count"] = gp['count'].cumsum().reset_index()["count"]
gp["cum_count_history"] = gp["cum_count"] - gp["count"]
index | user_id | brand_id | day | cum_count_history |
---|
0 | A | X | 1 | 0 |
1 | A | X | 2 | 1 |
2 | A | X | 3 | 3 |
3 | A | X | 4 | 4 |
key历史第几次取value
一般可以用rank实现“key内部value第几次取某个值”,例如“用户user_id历史第几次搜索品牌X”,这时一般要对时间列取rank()。例如下面这个DataFrame:
user_id | brand_id | timestamp |
---|
A | X | 20180401 |
A | Y | 20180402 |
A | X | 20180403 |
A | Y | 20180401 |
A | Y | 20180403 |
gp = data.groupby(["user_id","brand_id"])["timestamp"].rank().reset_index()
gp.rename(columns={"timestamp":"rank"},inplace=True)
index | rank |
---|
0 | 1.0 |
1 | 2.0 |
2 | 2.0 |
3 | 1.0 |
4 | 3.0 |
key当天第几次取value
还可以实现“用户每天第几次搜索品牌X”这样的特征,例如下面这个DataFrame:
user_id | brand_id | day | hour |
---|
A | X | 1 | 10 |
A | X | 1 | 11 |
A | Y | 1 | 16 |
A | Y | 1 | 15 |
A | Y | 1 | 14 |
首先按【用户-品牌-天】进行聚合,接下来用更小的可分的时间粒度(即小时)取rank。
gp = data.groupby(["user_id","day","brand_id"])["hour"].rank().reset_index()
gp.rename(columns={"hour":"rank"},inplace=True)
index | rank |
---|
0 | 1.0 |
1 | 2.0 |
2 | 3.0 |
3 | 2.0 |
4 | 1.0 |
参考资料
pandas groupby API
(仍在更新中)