棘手的 Python 数组排序
Tricky Python array sorting
目前,我正在将一些数据加载到内存中,格式如下:
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] 很简单,但问题是列表没有排序,第二列和第三列中的条目是浮点数,所以我不能在切片。
我试过双for循环方法,但它不能正常工作。
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 运行,此方法是否有效?
谢谢。
如果我理解你的问题,那么我猜你想根据索引对数组进行排序。为此,您可以使用 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.]])
由于您的矩阵非常小 (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)
试试这个:
mat = np.zeros((40,40))
for i in range(0,len(data_res)):
mat[data_res[1] , data_res[2]] = data_res[0]
你的循环没有工作,因为你的 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 提供的第二个示例是执行此操作的更简洁的方法,也是更强大的解决方案。
这可以在没有显式循环的情况下完成。我将使用较小的数据集,并创建一个 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]])
目前,我正在将一些数据加载到内存中,格式如下:
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] 很简单,但问题是列表没有排序,第二列和第三列中的条目是浮点数,所以我不能在切片。
我试过双for循环方法,但它不能正常工作。
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 运行,此方法是否有效?
谢谢。
如果我理解你的问题,那么我猜你想根据索引对数组进行排序。为此,您可以使用 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.]])
由于您的矩阵非常小 (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)
试试这个:
mat = np.zeros((40,40))
for i in range(0,len(data_res)):
mat[data_res[1] , data_res[2]] = data_res[0]
你的循环没有工作,因为你的 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 提供的第二个示例是执行此操作的更简洁的方法,也是更强大的解决方案。
这可以在没有显式循环的情况下完成。我将使用较小的数据集,并创建一个 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]])