在 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
我正在尝试建立期刊共现的稀疏矩阵 (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