Python 基于数据帧中的唯一值生成大量列
假设我有以下数据帧:Python 基于数据帧中的唯一值生成大量列,python,pandas,dataframe,Python,Pandas,Dataframe,假设我有以下数据帧: user_id | a1 | a2 | a3 | a4 | a5 | ... | a100 1 | 12 | 30 | 0 | 12 | 1 | ... | 21 2 | 2 | 13 | 18 | 13 | 13 | ... | 3 3 | 42 | 31 | 5 | 14 | 26 | ... | 41 4 | 1 | 9 | 10 | 15 | 20 | ... | 2
user_id | a1 | a2 | a3 | a4 | a5 | ... | a100
1 | 12 | 30 | 0 | 12 | 1 | ... | 21
2 | 2 | 13 | 18 | 13 | 13 | ... | 3
3 | 42 | 31 | 5 | 14 | 26 | ... | 41
4 | 1 | 9 | 10 | 15 | 20 | ... | 23
1AndAbove | 2AndAbove | ... | 42AndAbove
5 | 4 | ... | 0
6 | 6 | ... | 0
6 | 6 | ... | 2
6 | 5 | ... | 0
基于此数据帧,我希望为a1-a100列中的任何唯一值生成其他列。我认为最好用一个例子来解释这一点。基于上面的数据帧,我会将以下列附加到原始数据帧:
user_id | a1 | a2 | a3 | a4 | a5 | ... | a100
1 | 12 | 30 | 0 | 12 | 1 | ... | 21
2 | 2 | 13 | 18 | 13 | 13 | ... | 3
3 | 42 | 31 | 5 | 14 | 26 | ... | 41
4 | 1 | 9 | 10 | 15 | 20 | ... | 23
1AndAbove | 2AndAbove | ... | 42AndAbove
5 | 4 | ... | 0
6 | 6 | ... | 0
6 | 6 | ... | 2
6 | 5 | ... | 0
例如,42AndAbove列中的值显示,只有第三个用户的值大于等于42,并且有两次
我可以使用以下代码逐一执行此操作:
df['1AndAbove'] = (df > 1).astype(int).sum(axis=1)
但是,如果我需要生成100列,这将非常麻烦。我想知道是否有一种更通用、更优雅的方法可以做到这一点?IIUIC,您可以先过滤
a*
列,然后循环检查1-2个值的范围
In [382]: df_a = df.filter(like='a')
In [385]: for x in range(1, 43):
...: df['%sAndAbove' % x] = (df_a >= x).sum(axis=1)
...:
结果
In [386]: df
Out[386]:
user_id a1 a2 a3 a4 a5 a100 1AndAbove 2AndAbove 3AndAbove \
0 1 12 30 0 12 1 21 5 4 4
1 2 2 13 18 13 13 3 6 6 5
2 3 42 31 5 14 26 41 6 6 6
3 4 1 9 10 15 20 23 6 5 5
... 33AndAbove 34AndAbove 35AndAbove 36AndAbove 37AndAbove \
0 ... 0 0 0 0 0
1 ... 0 0 0 0 0
2 ... 2 2 2 2 2
3 ... 0 0 0 0 0
38AndAbove 39AndAbove 40AndAbove 41AndAbove 42AndAbove
0 0 0 0 0 0
1 0 0 0 0 0
2 2 2 2 2 1
3 0 0 0 0 0
[4 rows x 49 columns]
以下是矢量化方法:
pd.get_dummies(df.stack()).sum(level=0).iloc[:,::-1].cumsum(axis=1).iloc[:,::-1]
Out[83]:
0 1 2 3 5 9 10 12 13 14 15 18 20 21 23 26 30 \
user_id
1 6 5 4 4 4 4 4 4 2 2 2 2 2 2 1 1 1
2 6 6 6 5 4 4 4 4 4 1 1 1 0 0 0 0 0
3 6 6 6 6 6 5 5 5 5 5 4 4 4 4 4 4 3
4 6 6 5 5 5 5 4 3 3 3 3 2 2 1 1 0 0
31 41 42
user_id
1 0 0 0
2 0 0 0
3 3 2 1
4 0 0 0
你应该能够很容易地在循环中完成它,不确定是否有矢量化的方法来完成它。@JohnGalt矢量化的方法如下谢谢你,先生,在你评论之后,我有点明白了!美好的非常有趣的解决方案!