如何从邻接列表中有效地创建稀疏邻接矩阵?

时间:2017-01-13 06:37:26

标签: python pandas numpy

我正在使用last.fm中的Million song dataset数据集。 数据以一组json编码的文本文件的形式提供,其中的键是:track_id,artist,title,timestamp,similars和tags。

使用similars和track_id字段,我尝试创建稀疏邻接矩阵,以便我可以使用数据集进一步执行其他任务。以下是我的尝试。但是,它非常慢(特别是to_sparseopeningloading所有json个文件,最慢的是apply函数I&#39尽管经过一些改进后,我们还是想出来:/)。我是大熊猫的新手,我从第一次尝试起就改进了这一点,但我确信某些矢量化或其他方法会显着提高速度和效率。

import os
import pandas as pd
import numpy as np

# Path to the dataset
path = "../lastfm_subset/"

# Getting list of all json files in dataset
all_files = [os.path.join(root,file) for root, dirs, files in os.walk(path) for file in files if file.endswith('.json')] 

data_list=[json.load(open(file)) for file in all_files]
df = pd.DataFrame(data_list, columns=['similars', 'track_id'])
df.set_index('track_id', inplace=True)

a = pd.DataFrame(0,columns= df.index, index=df.index).to_sparse()

def make_graph(adjacent):
    importance = 1/len(adjacent['similars'])
    neighbors = list(filter(lambda x: x[1] > threshold, adjacent['similars']))
    if len(neighbors) == 0:
        return

    t_id, similarity_score  = map(list, zip(*neighbors))
    a.loc[list(t_id), adjacent['track_id']] = importance


df[( df['similars'].str.len() > 0 )].reset_index()[['track_id','similars']].apply(make_graph, axis=1)

我也相信阅读数据集的方式可以大大改进,也可以更好地编写。

因此,我们只需要读取数据,然后以有效的方式从邻接列表中生成稀疏邻接矩阵。

similars键有一个列表列表。内部列表是1x2,track_id具有相似的歌曲和相似度得分。

由于我是这门课程的新手,我愿意为这些任务的任何部分提供技巧,建议和更好的方法。

更新1

从评论中获取输入后,虽然它仍然远远没有达到可接受的速度,但是版本略好一些。好的部分,apply功能运行得相当快。但是,打开和加载json文件以使data_list的列表理解非常慢。而且,to_sparse需要永远,所以我没有创建稀疏矩阵。

import os
import pandas as pd
import numpy as np

# Path to the dataset
path = "../lastfm_subset/"

# Getting list of all json files in dataset
all_files = [os.path.join(root,file) for root, dirs, files in os.walk(path) for file in files if file.endswith('.json')] 

data_list=[json.load(open(file)) for file in all_files]
df = pd.DataFrame(data_list, columns=['similars', 'track_id'])
df.set_index('track_id', inplace=True)
df.loc[( df['similars'].str.len() > 0 ), 'importance' ] = 1/len(df['similars']) # Update 1


a = pd.DataFrame(df['importance'],columns= df.index, index=df.index)#.to_sparse(fill_value=0)

def make_graph(row):
    neighbors = list(filter(lambda x: x[1] > threshold, row['similars']))
    if len(neighbors) == 0:
        return

    t_id, similarity_score  = map(list, zip(*neighbors))
    a.loc[list(t_id), row['track_id']] = row['importance']


df[( df['similars'].str.len() > 0 )].reset_index()[['track_id','similar', 'importance']].apply(make_graph, axis=1)

更新2

使用生成器理解而不是列表理解。

data_list=(json.load(open(file)) for file in all_files)

我还在解析json文件时使用ujson来提高速度,这显然可以从this question here

中看到
try:
    import ujson as json
except ImportError:
    try:
        import simplejson as json
    except ImportError:
        import json

0 个答案:

没有答案