我有一个数百万条记录的数据集,其中包含100,000个用户,这些用户购买了20,000个项目的子集,格式如下:
<user1, item1>
<user1, item12>
...
<user100,000, item>
我需要跟踪大小矩阵(项目x用户)=(20,000 x 100,000),如果用户已购买该项,则为1,否则为零。目前我使用的是传统的numpy数组,但在后续步骤中处理它需要很长时间。任何人都可以推荐一种使用SciPy稀疏矩阵的有效方法,它仍然可以根据索引搜索矩阵吗?
答案 0 :(得分:3)
这是一个构建具有0和1的密集数据透视表的解决方案,然后创建等效的稀疏矩阵。我选择lil_matrix
,但存在其他选项。
import numpy as np
from scipy import sparse
ar = np.array([['user1', 'product1'], ['user2', 'product2'], ['user3', 'product3'], ['user3', 'product1']])
rows, r_pos = np.unique(ar[:,0], return_inverse=True)
cols, c_pos = np.unique(ar[:,1], return_inverse=True)
pivot_table = np.zeros((len(rows), len(cols)))
pivot_table[r_pos, c_pos] = 1
print(pivot_table)
# Convert the dense pivot table to a sparse matrix
s = sparse.lil_matrix(pivot_table)
# I can access the non-nul indices using nonzero
print(s.nonzero())
这给出了:
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 1. 0. 1.]]
(array([0, 1, 2, 2], dtype=int32), array([0, 1, 0, 2], dtype=int32))
附录
如果它是相关的,这是另一种不使用scipy的解决方案,而是pandas
:
In [34]: import pandas as pd
In [35]: df = pd.DataFrame([['user1', 'product1'], ['user2', 'product2'], ['user3', 'product3'], ['user3', 'product1']], columns = ['user', 'product'])
In [36]: df
Out[36]:
user product
0 user1 product1
1 user2 product2
2 user3 product3
3 user3 product1
In [37]: df.groupby(['user', 'product']).size().unstack(fill_value=0)
Out[37]:
product product1 product2 product3
user
user1 1 0 0
user2 0 1 0
user3 1 0 1
此外,请注意,这将计算每个客户购买的产品数量(这可能很有趣,具体取决于您的用例和数据集)。
您仍然可以使用此库搜索数据。