pandas: 使用groupby和unstack创建分类特征向量

5 投票
1 回答
6718 浏览
提问于 2025-04-18 11:17

我有一个pandas数据框,里面显示了用户在测试题目上的表现。它的样子是这样的:

userID     questionID   correct
-------------------------------
  1             1          1
  1             5          1
  1             6          0
  1             8          0
  1             10         1
  2             3          1
  2             5          1
  2             6          0
  .             .          .
  .             .          .
  .             .          .   

我想为每个用户制作一个特征向量,表示他们每道题是否答对了,结果应该像这样:

questionID     1     2      3     4     5     6     ...
userID       -------------------------------------------------
  1            1    NaN   NaN    NaN    1     0     ...
  2           NaN   NaN    1     NaN    1     0     ...
  .           ...
  .           ...
  .            

每个用户只会看到所有问题中的一部分,所以这是一个稀疏矩阵。

我该如何在pandas中制作上面的表格呢?

我想做的事情是先按用户ID和问题ID分组,然后再进行展开,但我不太确定具体该怎么操作。

df = df.groupby(['user_id','question_id'])
df.unstack()

谢谢你的帮助。

1 个回答

6

你在找的是pivot这个功能:

In [11]: df.pivot(values='correct', index='userID', columns='questionID')
Out[11]: 
questionID  1   3   5   6   8   10
userID                            
1            1 NaN   1   0   0   1
2          NaN   1   1   0 NaN NaN

如果你不想让所有问题都能对应到每一列,可能需要重新调整一下列的索引。

In [12]: _.reindex_axis(np.arange(1, 10), 1)
Out[12]: 
         1   2   3   4  5  6   7   8   9
userID                                  
1        1 NaN NaN NaN  1  0 NaN   0 NaN
2      NaN NaN   1 NaN  1  0 NaN NaN NaN

注意:最开始这个回答提到过pivot_table(这个功能在处理重复值时会用到一个聚合函数,默认是取平均值,而这不是你想要的 - 正如@U2EF1所指出的),它比pivot多了一些额外的功能,但速度稍微慢一点:

df.pivot_table(values='correct', rows='userID', cols='questionID')

我有种感觉,在早期版本的pandas中,pivot对NaN(缺失值)很敏感,所以你必须使用pivot_table...

撰写回答