在 Python 中填充稀疏矩阵的有效方法

Efficient way to populate a sparse matrix in Python

我正在尝试建立期刊共现的稀疏矩阵 (dok_matrix)。不幸的是,我的解决方案(太)低效,没有任何用处,而且我在网上找不到任何解决方案。

编辑:我还想直接创建稀疏矩阵,而不是先创建一个稠密矩阵,然后再将其变成稀疏矩阵。

我从一个数据框开始,该数据框显示某些期刊被一起引用的频率。在这个例子中,Nature 和 Science 一起被引用了 3 次。我想以一个稀疏的对称矩阵结束,其中行和列是期刊,非空条目是这些期刊被一起引用的频率。即,这里的完整矩阵将有四行(柳叶刀、自然、NEJM、科学)和四列(柳叶刀、自然、NEJM、科学)和三个非零条目。由于我的真实数据要大得多,所以我想使用稀疏矩阵表示。

我目前在我的代码中所做的是用我的 Dataframe 中的值更新非零条目。不幸的是,期刊名称的比较非常耗时,我的问题是,这里是否有更快的方法来设置稀疏矩阵。

我的理解是我的数据框无论如何都接近 dok_matrix,日志组合相当于 dok_matrix 中用作键的元组。但是,我不知道如何进行这种转变。

感谢任何帮助!

# Import packages
import pandas as pd
from scipy.sparse import dok_matrix

# Set up dataframe
d = {'journal_comb': ['Nature//// Science', 'NEJM//// Nature', 'Lancet//// NEJM'], 'no_combs': [3, 5, 6], 'journal_1': ['Nature', 'NEJM', 'Lancet'], 'journal_2': ['Science', 'Nature', 'NEJM']}
df = pd.DataFrame(d)

# Create list of all journal titles
journal_list = list(set(set(list(df['journal_1'])) | set(list(df['journal_2']))))
journal_list.sort()

# Set up empty sparse matrix with final size
S = dok_matrix((len(journal_list), len(journal_list)))

# Loop over all journal titles and get value from Dataframe for co-occuring journals
# Update sparse matrix value with value from Dataframe
for i in range(len(journal_list)):
    print i
    # Check whether journal name is actually in column 'journal_1'
    if len(df[(df['journal_1'] == journal_list[i])]) > 0:
    for j in range(len(journal_list)):
        # If clause to circumvent error due to empty series if journals are not co-cited
        if len(df[(df['journal_1'] == journal_list[i]) & (df['journal_2'] == journal_list[j])]['no_combs']) == 1:
            # Update value in sparse matrix
            S[i, j] = df[(df['journal_1'] == journal_list[i]) & (df['journal_2'] == journal_list[j])]['no_combs'].iloc[0]         

首先使用 pandas 塑造矩阵 -

dok_matrix(pd.concat([df, df.rename(index=str, columns={'journal_1' : 'journal_2', 'journal_2' : 'journal_1'})], axis=0).pivot(index='journal_1', columns = 'journal_2', values = 'no_combs').as_matrix())

我先将反向 journal1 添加为 journal 2,然后旋转以形成正确的形状,然后转换为矩阵,然后到 dok_matrix