正如标题所说,我试图通过更改以下测试脚本中的排序来验证numpy
数组中的排序:
import numpy as np
# Standard array
arr = [[1, 2, 3], [-7, -8, -9], ['A', 'B', 'C']]
print(arr, 'n')
for row_index, row_entries in enumerate(arr):
print('Row ' + str(row_index+1))
for column_index, column_entries in enumerate(row_entries):
print(' Column ' + str(column_index+1) + 'n', 't [' + str(column_entries) + ']')
# NumPy array
arr = np.asarray([[1, 2, 3], [-7, -8, -9], ['A', 'B', 'C']], order='F') # Try 'C' vs. 'F'!!
print('nn', arr, 'n')
for row_index, row_entries in enumerate(arr):
print('Row ' + str(row_index+1))
for column_index, column_entries in enumerate(row_entries):
print(' Column ' + str(column_index+1) + 'n', 't [' + str(column_entries) + ']')
----------------------------------------------------------------------------------------------
Output:
[[1, 2, 3], [-7, -8, -9], ['A', 'B', 'C']]
Row 1
Column 1
[1]
Column 2
[2]
Column 3
[3]
Row 2
Column 1
[-7]
Column 2
[-8]
Column 3
[-9]
Row 3
Column 1
[A]
Column 2
[B]
Column 3
[C]
[['1' '2' '3']
['-7' '-8' '-9']
['A' 'B' 'C']]
Row 1
Column 1
[1]
Column 2
[2]
Column 3
[3]
Row 2
Column 1
[-7]
Column 2
[-8]
Column 3
[-9]
Row 3
Column 1
[A]
Column 2
[B]
Column 3
[C]
为什么我得到相同的输出?
您从列表开始:
In [29]: alist = [[1, 2, 3], [-7, -8, -9], ['A', 'B', 'C']]
In [30]: alist
Out[30]: [[1, 2, 3], [-7, -8, -9], ['A', 'B', 'C']]
显然,我们可以遍历列表和子列表。
我们可以从这个列表中生成一个数组。通常我们不指定order
,但默认为"C":
In [31]: arr1 = np.array(alist, order='C')
In [32]: arr1
Out[32]:
array([['1', '2', '3'],
['-7', '-8', '-9'],
['A', 'B', 'C']], dtype='<U21')
注意,dtype是字符串(我想我本可以指定object
(。
相同的东西,但有"F":
In [34]: arr2 = np.array(alist, order='F')
In [35]: arr2
Out[35]:
array([['1', '2', '3'],
['-7', '-8', '-9'],
['A', 'B', 'C']], dtype='<U21')
显示内容相同。
为了了解元素是如何存储的,我们必须"遍历"数组。结果是一个新的1d数组。请参阅np.reshape
或np.ravel
文档了解"K"订单的使用:
In [36]: arr1.ravel('K')
Out[36]: array(['1', '2', '3', '-7', '-8', '-9', 'A', 'B', 'C'], dtype='<U21')
In [38]: arr2.ravel('K')
Out[38]: array(['1', '-7', 'A', '2', '-8', 'B', '3', '-9', 'C'], dtype='<U21')
在这里,我们沿着列读取arr2
的值。第一个数组的ravel
,但与"F"顺序产生相同的东西:
In [39]: arr1.ravel('F')
Out[39]: array(['1', '-7', 'A', '2', '-8', 'B', '3', '-9', 'C'], dtype='<U21')
正如您所做的,迭代不会随着order
而改变。它有效地将数组视为列表。
In [40]: [row for row in arr1]
Out[40]:
[array(['1', '2', '3'], dtype='<U21'),
array(['-7', '-8', '-9'], dtype='<U21'),
array(['A', 'B', 'C'], dtype='<U21')]
In [41]: [row for row in arr2]
Out[41]:
[array(['1', '2', '3'], dtype='<U21'),
array(['-7', '-8', '-9'], dtype='<U21'),
array(['A', 'B', 'C'], dtype='<U21')]
In [42]: arr2.tolist()
Out[42]: [['1', '2', '3'], ['-7', '-8', '-9'], ['A', 'B', 'C']]
您必须使用numpy's
自己的方法和工具才能看到order
的效果。order
在通过reshape
:创建阵列时更有用
In [43]: np.arange(12)
Out[43]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [44]: np.arange(12).reshape(3,4)
Out[44]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [45]: np.arange(12).reshape(3,4,order='F')
Out[45]:
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])
调整形状,然后应用转置:
In [46]: np.arange(12).reshape(4,3,order='F')
Out[46]:
array([[ 0, 4, 8],
[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11]])
In [47]: np.arange(12).reshape(4,3,order='F').T
Out[47]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
编辑
如果我制作一个较小的数组,每个元素只有1个字节,可能会更清楚。
两个订单:
In [70]: arr1 = np.array([[1,2,3],[4,5,6]], 'uint8')
In [72]: arr2 = np.array([[1,2,3],[4,5,6]], 'uint8',order='F')
In [73]: arr1
Out[73]:
array([[1, 2, 3],
[4, 5, 6]], dtype=uint8)
In [74]: arr2
Out[74]:
array([[1, 2, 3],
[4, 5, 6]], dtype=uint8)
代替ravel
,将tobytes
与"A"订单一起使用以保留基本订单(请参阅tobytes
文档(:
In [75]: arr1.tobytes(order='A')
Out[75]: b'x01x02x03x04x05x06'
In [76]: arr2.tobytes(order='A')
Out[76]: b'x01x04x02x05x03x06'
差异也可以从步伐中看出:
In [77]: arr1.strides
Out[77]: (3, 1)
In [78]: arr2.strides
Out[78]: (1, 2)
strides
控制numpy
如何在编译后的代码中遍历数组(但在使用python级别的迭代时则不然(。
一条评论建议使用nditer
通过numpy自己的方法进行迭代。一般来说,我不建议使用nditer
,但这里是说明性的:
In [79]: [i for i in np.nditer(arr1)]
Out[79]:
[array(1, dtype=uint8),
array(2, dtype=uint8),
array(3, dtype=uint8),
array(4, dtype=uint8),
array(5, dtype=uint8),
array(6, dtype=uint8)]
In [80]: [i for i in np.nditer(arr2)]
Out[80]:
[array(1, dtype=uint8),
array(4, dtype=uint8),
array(2, dtype=uint8),
array(5, dtype=uint8),
array(3, dtype=uint8),
array(6, dtype=uint8)]
nditer
采用order
,但"K"是默认值(与许多其他情况下"C"为默认值形成对比(。