numpy数组行主和列主

2024-06-06 03:16:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我很难理解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

这说明a是列主(F_CONTIGUOUS),因此,在内部,a应该如下所示:

[1, 4, 2, 5, 3, 6]

这正是本文glossary中所述。让我困惑的是,如果我试图以线性方式访问a的数据,我会得到:

>>> for i in xrange(6): print a.item(i)
... 
1.0
2.0
3.0
4.0
5.0
6.0

在这一点上,我不确定F_CONTIGUOUS标志告诉我们什么,因为它不遵守顺序。显然python中的所有内容都是row-major,当我们想以线性方式迭代时,可以使用迭代器^{}

问题如下:假设我们有一个数字列表,比如:1, 2, 3, 4, 5, 6,那么我们如何按照列主顺序创建一个numpy形状数组(2, 3)?我怎么才能得到这样的矩阵

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

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


Tags: 数据innumpyfalsetruefor顺序np
3条回答

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

虽然Kill Console的答案给出了OP所需的解决方案,但我认为需要注意的是,正如numpy.reforme()文档(https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html)中所述:

Note there is no guarantee of the memory layout (C- or Fortran- contiguous) of the returned array.

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

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

提供数据按列存储的更多保证(请参见https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.array.html中的顺序参数说明)。

你的问题已经得到了回答,但我想我可以补充这一点来解释你关于,“在这一点上,我不确定F_CONTIGUOUS标志告诉我们什么,因为它不遵守命令。”


item方法不像您想象的那样直接访问数据。为此,您应该访问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

以及

print c.nbytes == len(c.data)
# 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的数据是存储列major continuous的。

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]])

相关问题 更多 >