目前,我正在将一些数据加载到以下格式的内存中:
5.579158e-19 0 0
5.678307e-19 1 0
...
6.041513e-19 27 0
5.938317e-19 28 0
...
5.978803e-19 38 1
5.590008e-19 39 1
5.588807e-19 0 2
5.670948e-19 1 2
...
依此类推命令:
import numpy as np
data_res = np.genfromtxt('/path/data.csv',delimiter=';', dtype = float)
我想要的是40x40矩阵mat
,其中索引是第二和第三列中的条目。第一个条目mat [0,0] = data [0,0]很容易,但问题是列表没有排序,第二个和第三个列中的条目是浮点数所以我不能引用它们在切片中。
我尝试过双循环方法但它无法正常工作。
mat = np.zeros((40,40))
for k in range(0,40):
for j in range(0,40):
mat[k,j] = data_res[k*j,0]
如果索引从1-40开始而不是0-39,这个方法不会起作用吗?
感谢。
答案 0 :(得分:4)
这可以在没有显式循环的情况下完成。我将使用较小的数据集,并创建一个10x10数组mat
。如果索引(i,j)不在CSV文件中,mat[i,j]
将为0。
这是输入文件:
In [27]: !cat data.csv
0.1 0 0
0.2 1 0
0.3 7 0
0.4 8 0
0.5 8 1
0.6 9 1
0.7 0 2
0.8 1 2
0.9 9 9
使用genfromtxt
将数据读入包含三个字段values
,i
和j
的结构化数组中。
In [28]: data = np.genfromtxt('data.csv', dtype=None, names=['values', 'i', 'j'])
使用dtype=None
,我们会告诉genfromtxt
根据文件中的内容确定数据类型。在这种情况下,'values'
字段将为浮点数,字段'i'
和'j'
将为整数。
创建数组mat
:
In [29]: mat = np.zeros((10, 10))
将数据分配到mat
:
In [30]: mat[data['i'], data['j']] = data['values']
In [31]: mat
Out[31]:
array([[ 0.1, 0. , 0.7, 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0.2, 0. , 0.8, 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0.3, 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0.4, 0.5, 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0.6, 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.9]])
答案 1 :(得分:2)
如果我理解了你的问题,那么我猜你想根据索引对数组进行排序。为此,您可以使用numpy.lexsort
:
>>> arr = np.arange(16).reshape(4, 4).astype(float)
>>> x, y = arr.shape
>>> indices = np.vstack(np.unravel_index(np.arange(x*y), (y, x))).T
>>> np.random.shuffle(indices)
>>> arr = np.hstack((arr.flatten()[:, None], indices))
>>> arr # now this looks like your dataset, first column is data and other two are indices
array([[ 0., 1., 3.],
[ 1., 1., 2.],
[ 2., 3., 0.],
[ 3., 0., 1.],
[ 4., 0., 0.],
[ 5., 2., 0.],
[ 6., 0., 2.],
[ 7., 2., 3.],
[ 8., 3., 2.],
[ 9., 0., 3.],
[ 10., 3., 1.],
[ 11., 1., 0.],
[ 12., 3., 3.],
[ 13., 1., 1.],
[ 14., 2., 2.],
[ 15., 2., 1.]])
>>> arr[np.lexsort((arr[:, 2], arr[:,1]))][:,0].reshape(4, 4)
array([[ 4., 3., 6., 9.],
[ 11., 13., 1., 0.],
[ 5., 15., 14., 7.],
[ 2., 10., 8., 12.]])
答案 2 :(得分:1)
由于您的矩阵非常小(40x40),因此用于读取文件并输入numpy数组的纯python解决方案对您来说可能更好:
raw = '''5.579158e-19 0 0
5.678307e-19 1 0
6.041513e-19 27 0
5.588807e-19 0 2
5.670948e-19 1 2'''
import numpy as np
mat = np.zeros((40,40))
for line in raw.split('\n'):
z,i,j = line.split()
mat[int(i),int(j)]=float(z)
print mat
上面的示例使用字符串来保存文件示例的数据。如果文件名为data.txt
,则会运行:
with open("data.txt") as FIN:
for line in FIN:
z,i,j = line.split()
mat[int(i),int(j)]=float(z)
答案 3 :(得分:1)
你的循环无效,因为data_res[k*j,0]
没有做我认为你想要的事情。
要获得所需的结果,请尝试data_res[(k*40)+j,0]
。
dim = 40
mat = np.zeros((dim,dim))
for k in range(0,dim):
for j in range(0,dim):
mat[k,j] = data_res[(k*dim)+j,0]
这是基于您的指标实际上已经排序的假设。正如ajcr指出的那样,如果他们不是,你将需要一个不同的方法。
更新:hooked提供的第二个示例是更简洁的方法,也是一个更强大的解决方案。
答案 4 :(得分:-1)
试试这个:
mat = np.zeros((40,40))
for i in range(0,len(data_res)):
mat[data_res[1] , data_res[2]] = data_res[0]