我有一个元组列表如下:
[(x,{'y':'1,3','z':'2'}),
(y,{'a':'4'}),
(z,{'b':'2,3'})]
我需要将其转换为numpy数组格式,如下所示:
x y z a b
x 0 1,3 2 0 0
y 1,3 0 0 4 0
z 2 0 0 0 2,3
a 0 4 0 0 0
b 0 0 2,3 0 0
为了支持这一点,请将node-name存储为列表,以便为它们提供映射索引。
[x,y,z,a,b]
给出索引 - 从这个结构创建numpy数组的最有效方法是什么? 此外 - 当新条目进入原始元组列表时,它将根据需要添加到索引列表和numpy数组中。
不会发生现有元素的编辑。
非常感谢帮助。
答案 0 :(得分:1)
如果您使用object
dtypes,则可以使用以下方法构建阵列。由于您需要2D对称,因此首先创建2D数组并从此构建结构化数组更容易:
import numpy as np
o = ['x','y','z','a','b']
a = np.zeros((len(o),len(o)),dtype=object)
s =[('x',{'y':'1,3','z':'2'}), ('y',{'a':'4'}), ('z',{'b':'2,3'})]
for vi in s:
i = o.index(vi[0])
for vj in vi[1].items():
j = o.index(vj[0])
a[i,j] = vj[1]
a[j,i] = a[i,j]
# building the structured array
b = np.zeros((len(o),), dtype=[(i,object) for i in o])
for i,vi in enumerate(o):
b[vi] = a[i,:]
# building a dictionary to access the values
d = dict(( (vi, dict(( (vj, a[i,j]) for j,vj in enumerate(o) ))) for i,vi in enumerate(o) ))
答案 1 :(得分:0)
更多numpythonic版本......值存储为字符串。这可以改变,但您可能需要更好地定义输入的dicts列表的语法:
import numpy as np
import operator as op
data = [('x', {'y' : '1,3', 'z' : '2'}),
('y', {'a' : '4'}),
('z', {'b' : '2,3'})]
keys = np.array(['x', 'y', 'z', 'a', 'b'])
keys_sort = np.argsort(keys)
rows = [(item[0], item[1].keys(), item[1].values()) for item in data]
rows = np.array(reduce(op.add, ([item[0]]*len(item[1]) for item in data)))
cols = np.array(reduce(op.add, (item[1].keys() for item in data)))
vals = np.array(reduce(op.add, (item[1].values() for item in data)))
row_idx = keys_sort[np.searchsorted(keys, rows, sorter=keys_sort)]
col_idx = keys_sort[np.searchsorted(keys, cols, sorter=keys_sort)]
out_arr = np.empty((len(keys), len(keys)), dtype=vals.dtype)
out_arr[:] = '0'
out_arr[row_idx, col_idx] = vals
out_arr[col_idx, row_idx] = vals
>>> out_arr
array([['0', '1,3', '2', '0', '0'],
['1,3', '0', '0', '4', '0'],
['2', '0', '0', '0', '2,3'],
['0', '4', '0', '0', '0'],
['0', '0', '2,3', '0', '0']],
dtype='|S3')