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矢量化的方法如下谢谢你,先生,在你评论之后,我有点明白了!美好的非常有趣的解决方案!