Python中将CSV转换为稀疏矩阵

9

我有一个大的csv文件,其中列出了图中节点之间的连接。例如:

0001,95784
0001,98743
0002,00082
0002,00091

这意味着节点id 0001与节点95784和98743等相连。 我需要将其读入numpy中的稀疏矩阵。我该怎么做? 由于我是python新手,因此教程也会对我有所帮助。


在你想要的矩阵术语中,“0001连接到95784”是什么意思? - kender
这意味着节点(id: 0001)与节点(id: 95784)之间存在有向链接。 - Ankur Chauhan
3个回答

12

使用 lil_matrix (列表列表矩阵) 的示例,属于scipy。

基于行的链表矩阵。

它包含一列(self.rows)行,每行都是非零元素列索引的已排序列表。 它还包含这些元素的列表(self.data)列表。

$ cat 1938894-simplified.csv
0,32
1,21
1,23
1,32
2,23
2,53
2,82
3,82
4,46
5,75
7,86
8,28

代码:

#!/usr/bin/env python

import csv
from scipy import sparse

rows, columns = 10, 100
matrix = sparse.lil_matrix( (rows, columns) )

csvreader = csv.reader(open('1938894-simplified.csv'))
for line in csvreader:
    row, column = map(int, line)
    matrix.data[row].append(column)

print matrix.data

输出:

[[32] [21, 23, 32] [23, 53, 82] [82] [46] [75] [] [86] [28] []]

正是我所需要的。你能推荐一些好的scipy资源吗? - Ankur Chauhan
一个小问题。CSV文件中的数字不是索引,而是ID。这个文件以以下格式开始: 0001001,9304045 0001001,9308122 0001001,9309097 0001001,9311042 0001001,9401139 0001001,9404151 0001001,9407087 0001001,9408099 0001001,9501030 0001001,9503124那么我该如何将这些ID转换为数字索引?ID仅用于标识节点,如果它们是唯一的,则可以用等效的索引替换它们。我应该怎么做呢?我知道可以将行和列设置为最大ID,但这似乎很浪费,因为索引0到1001的节点都被浪费了。 - Ankur Chauhan
我理解你的关注,并且我认为,没有一种最好的方法来“压缩”你的数据到相关元素。这在很大程度上取决于你的目标,以及你之后想要如何处理这些数据。例如,你可以使用一个“映射字典”,将实际ID映射到一些较小的数值... - miku
如果您确实想要“挤压”索引,使它们从0开始以1的增量逐步上升到某个最大值,为什么不采取以下步骤:(1)对它们进行排序,生成sorted_ixssorted_ixs = ixs; sorted_ixs.sort()),(2)使用zip(sorted_ixs, range(len(sorted_ixs))生成一个匹配索引与“挤压索引”的一对列表,(3)将该列表用作从旧索引到新索引的“翻译表”。 - Michał Marczyk
实际上,我认为这也会对“ixs”进行排序;如果您想保留未排序的“ixs”,请使用“sorted_ixs = ixs[:]”。 - Michał Marczyk

2
如果你想要一个邻接矩阵,可以这样做:
from scipy.sparse import *
from scipy import *
from numpy import *
import csv
S = dok_matrix((10000,10000), dtype=bool)
f = open("your_file_name")
reader = csv.reader(f)
for line in reader:
    S[int(line[0]),int(line[1])] = True

2
你可能也会对Networkx感兴趣,这是一个纯Python的网络/图形包。
从网站上来看:
NetworkX是一个Python包,用于创建、操作和研究复杂网络的结构、动态和功能。
>>> import networkx as nx
>>> G=nx.Graph()
>>> G.add_edge(1,2)
>>> G.add_node("spam")
>>> print G.nodes()
[1, 2, 'spam']
>>> print G.edges()
[(1, 2)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接