当您调用numpy.array
从现有的Python对象创建一个数组时,它会返回一个具有与原始Python对象相同的任何形状的对象。因此,
np.array([[1,2],[3,4]], ...)
永远会给予你,
np.array([[1, 2],
[3, 4]])
这正是您键入的内容,所以不应该感到惊讶。Fortran顺序和C顺序并不描述数据的形状,而是描述内存布局。当您打印一个对象时,NumPy不会显示内存布局,它只会显示形状。
当您使用"K"
顺序将其展平时,可以看到数组确实按Fortran顺序存储,该顺序保持元素的原始顺序:
>>> a = np.array([[1,2],[3,4]], order="F")
>>> a.flatten(order="K")
array([1, 3, 2, 4])
这正是区分Fortran和C的真正区别所在:内存布局。大多数NumPy函数不强制您考虑内存布局,而是透明地处理不同的布局。
听起来你想要的是转置,即反转轴顺序。这可以简单地完成:
>>> b = numpy.transpose(a)
>>> b
array([[1, 3],
[2, 4]])
这并不会创建一个新的数组,而是创建了原数组的一个新视图:
>>> b.base is a
True
如果你想让数据在内存中保持1 2 3 4的布局,并且具有[[1, 3], [2, 4]]的Fortran视图,有效的做法是使用C顺序存储现有数组,然后对其进行转置,这将得到所需内容的Fortran顺序数组,并且不需要额外复制。
>>> a = np.array([[1, 2], [3, 4]]).transpose()
>>> a.flatten(order="K")
array([1, 2, 3, 4])
>>> a
array([[1, 3],
[2, 4]])
如果您使用Fortran顺序存储原始数据,则转置后将得到C顺序,因此您不希望出现这种情况(或者您只关心转置,内存顺序并不重要?)。无论哪种情况,数组在NumPy中看起来都是相同的。
>>> a = np.array([[1, 2], [3, 4]], order="F").transpose()
>>> a.flatten(order="K")
array([1, 3, 2, 4])
>>> a
array([[1, 3],
[2, 4]])