在 Python 中创建稀疏矩阵
Create Sparse Matrix in Python
正在处理数据并希望创建一个稀疏矩阵以供以后用于聚类目的。
fileHandle = open('data', 'r')
for line in fileHandle:
json_list = []
fields = line.split('\t')
json_list.append(fields[0])
json_list.append(fields[1])
json_list.append(fields[3])
现在的数据是这样的:
term, ids, quantity
['buick', '123,234', '500']
['chevy', '345,456', '300']
['suv','123', '100']
我需要的输出是这样的:
term, quantity, '123', '234', '345', '456', '567'
buick, 500, 1, 1, 0, 0, 0
chevy, 300, 0, 0, 1, 1, 0
suv, 100, 1, 0, 0, 0, 0
我试过使用 numpy 稀疏矩阵库但没有成功。
我有一个偷懒的方法
data = [['term', 'ids', 'quantity'],
... ['buick', ['123', '234'], 500],
... ['chevy', ['345', '456'], 300],
... ['suv', ['123', '567'], 100]]
res = []
for i,line in enumerate(data):
... if i == 0:
... header = line
... else:
... temp = {}
... for j,ele in enumerate(line):
... if j in [0,2]:
... temp.update( {header[j] : ele} )
... else:
... for num in line[1]:
... temp.update( { num:1 } )
... res.append(temp)
with open(filepath,'wb') as f:
... w = csv.DictWriter(f,set( [ k for ele in res for k in ele.keys()] ))
... w.writeheader()
... w.writerows(res)
输出
term 456 567 345 123 234 quantity
buick 1 1 500
chevy 1 1 300
suv 1 1 100
scikit_learn
可能有工具可以轻松做到这一点,但我将演示一个基本的 Python/numpy 解决方案。
原始数据 - 列表列表
In [1150]: data=[['buick', '123,234', '500'],
['chevy', '345,456', '300'],
['suv','123', '100']]
我可以通过列表理解提取出许多列。在非常大的情况下,这可能不是最快的,但就目前而言,这是一种逐个解决问题的简单方法。
In [1151]: terms=[row[0] for row in data]
In [1152]: terms
Out[1152]: ['buick', 'chevy', 'suv']
In [1153]: quantities=[int(row[2]) for row in data]
In [1154]: quantities
Out[1154]: [500, 300, 100]
创建可能的 ID 列表。我可以从 data
中提取这些,但您显然使用了更大的列表。它们可以是字符串而不是整数。
In [1155]: idset=[123,234,345,456,567]
In [1156]: ids=[[int(i) for i in row[1].split(',')] for row in data]
In [1157]: ids
Out[1157]: [[123, 234], [345, 456], [123]]
np.in1d
是一个方便的工具,用于查找这些子列表在主列表中的位置。结果 idM
是特征矩阵,有很多 0 和一些 0。
In [1158]: idM=np.array([np.in1d(idset,i) for i in ids],int)
In [1159]: idM
Out[1159]:
array([[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0],
[1, 0, 0, 0, 0]])
我们可以 assemble 以各种方式拼凑。
例如,可以使用以下方式创建结构化数组:
In [1161]: M=np.zeros(len(data),dtype='U10,int,(5)int')
In [1162]: M['f0']=terms
In [1163]: M['f1']=quantities
In [1164]: M['f2']=idM
In [1165]: M
Out[1165]:
array([('buick', 500, [1, 1, 0, 0, 0]), ('chevy', 300, [0, 0, 1, 1, 0]),
('suv', 100, [1, 0, 0, 0, 0])],
dtype=[('f0', '<U10'), ('f1', '<i4'), ('f2', '<i4', (5,))])
idM
可以变成稀疏矩阵:
In [1167]: from scipy import sparse
In [1168]: c=sparse.coo_matrix(idM)
In [1169]: c
Out[1169]:
<3x5 sparse matrix of type '<class 'numpy.int32'>'
with 5 stored elements in COOrdinate format>
In [1170]: c.A
Out[1170]:
array([[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0],
[1, 0, 0, 0, 0]])
在这个探索中,先创建更密集的数组,然后从中创建一个稀疏数组更容易。
但是 sparse
提供了一个 bmat
函数,可以让我从单行矩阵的列表中创建多行矩阵。 (请参阅我的编辑历史,了解直接构建 coo
输入的版本)
In [1220]: ll=[[sparse.coo_matrix(np.in1d(idset,i),dtype=int)] for i in ids]
In [1221]: sparse.bmat(ll)
Out[1221]:
<3x5 sparse matrix of type '<class 'numpy.int32'>'
with 5 stored elements in COOrdinate format>
In [1222]: sparse.bmat(ll).A
Out[1222]:
array([[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0],
[1, 0, 0, 0, 0]], dtype=int32)
正在处理数据并希望创建一个稀疏矩阵以供以后用于聚类目的。
fileHandle = open('data', 'r')
for line in fileHandle:
json_list = []
fields = line.split('\t')
json_list.append(fields[0])
json_list.append(fields[1])
json_list.append(fields[3])
现在的数据是这样的:
term, ids, quantity
['buick', '123,234', '500']
['chevy', '345,456', '300']
['suv','123', '100']
我需要的输出是这样的:
term, quantity, '123', '234', '345', '456', '567'
buick, 500, 1, 1, 0, 0, 0
chevy, 300, 0, 0, 1, 1, 0
suv, 100, 1, 0, 0, 0, 0
我试过使用 numpy 稀疏矩阵库但没有成功。
我有一个偷懒的方法
data = [['term', 'ids', 'quantity'],
... ['buick', ['123', '234'], 500],
... ['chevy', ['345', '456'], 300],
... ['suv', ['123', '567'], 100]]
res = []
for i,line in enumerate(data):
... if i == 0:
... header = line
... else:
... temp = {}
... for j,ele in enumerate(line):
... if j in [0,2]:
... temp.update( {header[j] : ele} )
... else:
... for num in line[1]:
... temp.update( { num:1 } )
... res.append(temp)
with open(filepath,'wb') as f:
... w = csv.DictWriter(f,set( [ k for ele in res for k in ele.keys()] ))
... w.writeheader()
... w.writerows(res)
输出
term 456 567 345 123 234 quantity
buick 1 1 500
chevy 1 1 300
suv 1 1 100
scikit_learn
可能有工具可以轻松做到这一点,但我将演示一个基本的 Python/numpy 解决方案。
原始数据 - 列表列表
In [1150]: data=[['buick', '123,234', '500'],
['chevy', '345,456', '300'],
['suv','123', '100']]
我可以通过列表理解提取出许多列。在非常大的情况下,这可能不是最快的,但就目前而言,这是一种逐个解决问题的简单方法。
In [1151]: terms=[row[0] for row in data]
In [1152]: terms
Out[1152]: ['buick', 'chevy', 'suv']
In [1153]: quantities=[int(row[2]) for row in data]
In [1154]: quantities
Out[1154]: [500, 300, 100]
创建可能的 ID 列表。我可以从 data
中提取这些,但您显然使用了更大的列表。它们可以是字符串而不是整数。
In [1155]: idset=[123,234,345,456,567]
In [1156]: ids=[[int(i) for i in row[1].split(',')] for row in data]
In [1157]: ids
Out[1157]: [[123, 234], [345, 456], [123]]
np.in1d
是一个方便的工具,用于查找这些子列表在主列表中的位置。结果 idM
是特征矩阵,有很多 0 和一些 0。
In [1158]: idM=np.array([np.in1d(idset,i) for i in ids],int)
In [1159]: idM
Out[1159]:
array([[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0],
[1, 0, 0, 0, 0]])
我们可以 assemble 以各种方式拼凑。
例如,可以使用以下方式创建结构化数组:
In [1161]: M=np.zeros(len(data),dtype='U10,int,(5)int')
In [1162]: M['f0']=terms
In [1163]: M['f1']=quantities
In [1164]: M['f2']=idM
In [1165]: M
Out[1165]:
array([('buick', 500, [1, 1, 0, 0, 0]), ('chevy', 300, [0, 0, 1, 1, 0]),
('suv', 100, [1, 0, 0, 0, 0])],
dtype=[('f0', '<U10'), ('f1', '<i4'), ('f2', '<i4', (5,))])
idM
可以变成稀疏矩阵:
In [1167]: from scipy import sparse
In [1168]: c=sparse.coo_matrix(idM)
In [1169]: c
Out[1169]:
<3x5 sparse matrix of type '<class 'numpy.int32'>'
with 5 stored elements in COOrdinate format>
In [1170]: c.A
Out[1170]:
array([[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0],
[1, 0, 0, 0, 0]])
在这个探索中,先创建更密集的数组,然后从中创建一个稀疏数组更容易。
但是 sparse
提供了一个 bmat
函数,可以让我从单行矩阵的列表中创建多行矩阵。 (请参阅我的编辑历史,了解直接构建 coo
输入的版本)
In [1220]: ll=[[sparse.coo_matrix(np.in1d(idset,i),dtype=int)] for i in ids]
In [1221]: sparse.bmat(ll)
Out[1221]:
<3x5 sparse matrix of type '<class 'numpy.int32'>'
with 5 stored elements in COOrdinate format>
In [1222]: sparse.bmat(ll).A
Out[1222]:
array([[1, 1, 0, 0, 0],
[0, 0, 1, 1, 0],
[1, 0, 0, 0, 0]], dtype=int32)