我有一个大矩阵(约2亿行),描述了每天发生的操作的列表(可能有10000个操作)。我的最终目标是创建一个共现矩阵,显示在同一天发生了哪些操作。
这是一个示例数据集:
data = {'date': ['01', '01', '01', '02','02','03'],
'action': [100, 101, 989855552, 100, 989855552, 777]}
df = pd.DataFrame(data, columns = ['date','action'])
我想用pd.get_dummies创建一个稀疏矩阵,但是解开该矩阵并在其上使用groupby极其缓慢,仅花了6分钟即可获得5000行。
# Create a sparse matrix of dummies
dum = pd.get_dummies(df['action'], sparse = True)
df = df.drop(['action'], axis = 1)
df = pd.concat([df, dum], axis = 1)
# Use groupby to get a single row for each date, showing whether each action occurred.
# The groupby command here is the bottleneck.
cols = list(df.columns)
del cols[0]
df = df.groupby('date')[cols].max()
# Create a co-occurrence matrix by using dot-product of sparse matrices
cooc = df.T.dot(df)
我也尝试过:
但是我在步骤1中失败了,因为没有足够的RAM创建这么大的矩阵。
非常感谢您的帮助。
我根据这篇文章提出了一个仅使用稀疏矩阵的答案。代码很快,一千万行花了大约10秒的时间(我之前的代码花了5000分钟花了6分钟的时间,并且无法扩展)。
节省时间和内存的原因是使用稀疏矩阵,直到最后一步(需要在导出之前分解(已经很小)的共现矩阵)到最后一步时为止。
## Get unique values for date and action
date_c = CategoricalDtype(sorted(df.date.unique()), ordered=True)
action_c = CategoricalDtype(sorted(df.action.unique()), ordered=True)
## Add an auxiliary variable
df['count'] = 1
## Define a sparse matrix
row = df.date.astype(date_c).cat.codes
col = df.action.astype(action_c).cat.codes
sparse_matrix = csr_matrix((df['count'], (row, col)),
shape=(date_c.categories.size, action_c.categories.size))
## Compute dot product with sparse matrix
cooc_sparse = sparse_matrix.T.dot(sparse_matrix)
## Unravel co-occurrence matrix into dense shape
cooc = pd.DataFrame(cooc_sparse.todense(),
index = action_c.categories, columns = action_c.categories)