pandas: 使用groupby和unstack创建分类特征向量
我有一个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...