Python numpy数组行主数组和列主数组

Python numpy数组行主数组和列主数组,python,arrays,numpy,Python,Arrays,Numpy,我无法理解numpy如何存储数据。考虑以下事项: >>> import numpy as np >>> a = np.ndarray(shape=(2,3), order='F') >>> for i in xrange(6): a.itemset(i, i+1) ... >>> a array([[ 1., 2., 3.], [ 4., 5., 6.]]) >>> a.flags

我无法理解
numpy
如何存储数据。考虑以下事项:

>>> import numpy as np
>>> a = np.ndarray(shape=(2,3), order='F')
>>> for i in xrange(6): a.itemset(i, i+1)
... 
>>> a
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])
>>> a.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
[1, 4, 2, 5, 3, 6]
这表示
a
是主列(
F_continuous
),因此,在内部,
a
应如下所示:

>>> import numpy as np
>>> a = np.ndarray(shape=(2,3), order='F')
>>> for i in xrange(6): a.itemset(i, i+1)
... 
>>> a
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.]])
>>> a.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
[1, 4, 2, 5, 3, 6]
这正是本文所说的。让我困惑的是,如果我试图以线性方式访问
a
的数据,我会得到:

>>> for i in xrange(6): print a.item(i)
... 
1.0
2.0
3.0
4.0
5.0
6.0
在这一点上,我不确定F_continuous标志告诉我们什么,因为它不尊重订单。显然,python中的所有内容都是行主要的,当我们想要以线性方式进行迭代时,我们可以使用迭代器

问题如下:假设我们有一个数字列表,比如:
1,2,3,4,5,6
,我们如何创建一个
numpy
数组,数组的形状
(2,3)
?这就是如何得到一个像这样的矩阵

array([[ 1.,  3.,  5.],
       [ 2.,  4.,  6.]])

我真的希望能够在列表上进行线性迭代,并将它们放入新创建的
ndarray
。这是因为我将读取按列主顺序设置的多维数组的文件

numpy按行的主要顺序存储数据

>>> a = np.array([[1,2,3,4], [5,6,7,8]])
>>> a.shape
(2, 4)
>>> a.shape = 4,2
>>> a
array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])
如果更改形状,则数据的顺序不会更改

如果你加上一个“F”,你就能得到你想要的

>>> b
array([1, 2, 3, 4, 5, 6])
>>> c = b.reshape(2,3,order='F')
>>> c
array([[1, 3, 5],
       [2, 4, 6]])

通常,numpy使用order来描述内存布局,但是无论内存布局如何,数组的python行为都应该是一致的。我认为使用视图可以获得所需的行为。视图是与另一个数组共享内存的数组。例如:

import numpy as np

a = np.arange(1, 6 + 1)
b = a.reshape(3, 2).T

a[1] = 99
print b
# [[ 1  3  5]
#  [99  4  6]]

希望这会有所帮助。

您的问题已经得到了回答,但我想我会添加这一点来解释您的观察结果:“在这一点上,我不确定F_连续标志告诉我们什么,因为它不遵守订单。”


方法不像您认为的那样直接访问数据。为此,您应该访问
data
属性,该属性为您提供字节字符串

例如:

c = np.array([[1,2,3],
              [4,6,7]], order='C')

f = np.array([[1,2,3],
              [4,6,7]], order='F')
观察

print c.flags.c_contiguous, f.flags.f_contiguous
# True, True

现在,让我们打印这两个对象的连续数据:

nelements = np.prod(c.shape)
bsize = c.dtype.itemsize # should be 8 bytes for 'int64'
for i in range(nelements):
    bnum = c.data[i*bsize : (i+1)*bsize] # The element as a byte string.
    print np.fromstring(bnum, dtype=c.dtype)[0], # Convert to number.
这张照片是:

1 2 3 4 6 7
这就是我们所期望的,因为
c
是顺序
'c'
,也就是说,它的数据是连续存储的

另一方面,

nelements = np.prod(f.shape)
bsize = f.dtype.itemsize # should be 8 bytes for 'int64'
for i in range(nelements):
    bnum = f.data[i*bsize : (i+1)*bsize] # The element as a byte string.
    print np.fromstring(bnum, dtype=f.dtype)[0], # Convert to number.
印刷品

1 4 2 6 3 7

这也是我们希望看到的,因为
f
的数据存储在列主连续中。

下面是一种使用
ravel()
函数按内存顺序打印数据的简单方法:

>>> import numpy as np
>>> a = np.ndarray(shape=(2,3), order='F')
>>> for i in range(6): a.itemset(i, i+1)

>>> print(a.ravel(order='K'))
[ 1.  4.  2.  5.  3.  6.]

这确认数组是以Fortran顺序存储的。

希望在注释中添加此内容,但我的代表太低:

Kill Console的回答给出了OP所需的解决方案,但我认为需要注意的是,正如numpy.reforme()文档()中所述:

注意:不能保证返回数组的内存布局(C-或Fortran-连续)

因此,即使视图按列显示,数据本身也可能不按列显示,这可能会导致计算效率低下,这得益于将数据按列存储在内存中。也许:

a = np.array(np.array([1, 2, 3, 4, 5, 6]).reshape(2,3,order='F'), order='F')

提供了更多的保证,即数据是按列存储的(请参见中的顺序参数说明)。

您可以重新格式化吗?@dvreed77 restrape仅更改形状,而不是顺序我已检查了重新格式化的文档,它显示“顺序:{'C'、'F'、'a'},可选决定数组数据是否应按C(行主键)查看顺序、FORTRAN(列主)顺序或C/FORTRAN顺序应该保留。因此,我想它只是更改视图,而不是它存储的顺序。顺序才是需要更改的顺序。我想没有别的办法了。我不得不承认matlab是以列为主,python是以行为主。没有什么比创建一个
(3,2)
数组然后使用
转置更好的了吗?@jmlopez在创建数组时,您可以提供一个关键字参数
顺序
。如果已经创建了它,可以使用
.reformate(order=…)
方法。此处的信息@jmlopez仅用于将Matlab数据转换为numpy格式。您应该保持标准的numpy顺序,否则在应用numpy函数时可能会复制数据。我喜欢这个答案,但
np。fromstring
在Python3中不再像这样工作,导致TypeError:fromstring()参数1必须是只读字节,类似于object,而不是memoryview。相反,我尝试使用
frombuffer
作为
print(np.frombuffer(bnum,dtype=f.dtype))
,这对行顺序数据有效,但对列顺序数据无效,BufferError:memoryview:基础缓冲区不是C连续的。所以我还不确定如何确认这里描述的底层数据顺序。