在对Numpy进行实验时,我发现numpy.info提供的连续值可能与numpy.ndarray.data.contiguous不同(请参阅下面的代码和屏幕快照)。
import numpy as np
x = np.arange(9).reshape(3,3)[:,(0,1)]
np.info(x)
print(f'''
{x.data.contiguous = }
{x.flags.contiguous = }
{x.data.c_contiguous = }
{x.flags.c_contiguous = }
{x.data.f_contiguous = }
{x.flags.f_contiguous = }
''')根据关于内存视图类的文档,如果数组是C-毗连或Fortran毗连的话,则是data.contiguous == True。至于numpy.info,我相信它显示了flags.contiguous的值。唉,在手册中没有关于它的任何信息。这到底是什么意思?它是flags.c_contiguous的synonim吗?

发布于 2022-05-19 03:15:52
在源代码 of numpy.info中,我们可以看到处理ndarray的子例程。
def info(object=None, maxwidth=76, output=None, toplevel='numpy'):
...
elif isinstance(object, ndarray):
_info(object, output=output)
...
def _info(obj, output=None):
"""Provide information about ndarray obj"""
bp = lambda x: x
...
print("contiguous: ", bp(obj.flags.contiguous), file=output)
print("fortran: ", obj.flags.fortran, file=output)
...它返回flags.contiguous作为数组的连续性参数。这一项没有在标志描述中指定。但我们可以在flagsobject.c上找到它
// ...
static PyGetSetDef arrayflags_getsets[] = {
{"contiguous",
(getter)arrayflags_contiguous_get,
NULL,
NULL, NULL},
{"c_contiguous",
(getter)arrayflags_contiguous_get,
NULL,
NULL, NULL},
// ...现在很清楚,来自numpy.info的numpy.info参数实际上是flags.c_contiguous,与ndarray.data.contiguous没有任何共同之处。我想,在用C进行编程时,只使用contiguous而不是c_contiguous是很自然的,这就导致了术语上的一点不一致。
发布于 2022-05-18 18:48:22
x = np.arange(9).reshape(3,3)[:,(0,1)]np.arange(9)生成一个一维数组;reshape(3,3)将其重组为2d。它是原始view的arange。如果没有order参数,reshape就会使用默认的c-order。
[0,[0,1]]是高级索引,制作一个副本。使用[0,:2]索引将选择相同的值,但会生成一个view。
info的大步是(8,24)。重塑后的strides用于x应该是(24,8),最后一个维度为8个字节,第一个维度为3*8。但是高级索引会翻转周围的东西--这是我们通常忽略(或不知道)的索引的细节。
第一步较小的二维数组是F-order。
我不会试图破译所有的数据/平面图连续打印,但基本的布局对我来说是显而易见的形状和步伐。我认为跨越式是优先的,所有的“连续”显示都是派生的,可以说是对跨越式发展的解释。
使用3d (或更高)数组,contiguous替代方案可以分解。可以像(48,8,24)这样的步幅来制作一个数组,其中中间维的步数最快。这既不拥挤也不拥挤。
我可以补充说,除非你做的是
np.arange(9).reshape(3,3, order='F')毗连的类型通常不是我们所担心的。某些功能(尤指)(编译的)要求一定的连续性。一些操作更快(或更慢),这取决于哪个维度是“最内部的”。但是对于普通的numpy使用,我不太注意flags。在我使用numpy多年之后,我才意识到您的示例索引翻转了order。
你本可以只显示x.flags。我不知道显示x.data为您做了什么。
编辑
x,在我的会话中创建为int32
x
Out[28]:
array([[0, 1],
[3, 4],
[6, 7]])
x.strides
Out[29]: (4, 12)我通常使用__array_interface__而不是np.info,但信息类似:
x.__array_interface__
Out[30]:
{'data': (1175190303648, False),
'strides': (4, 12),
'descr': [('', '<i4')],
'typestr': '<i4',
'shape': (3, 2),
'version': 3}我通常看的是strides而不是标志,但下面是完整的显示:
x.flags
Out[31]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : False
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False为什么owndata是假的?显然,索引实际上创建了:
x.base
Out[32]:
array([[0, 3, 6],
[1, 4, 7]])然后返回转置。c_contiguous数组的转置是f_contiguous。
如果我创建相同的数组(valuewise),但是通过切片,就会得到一个在任何意义上都不是连续的view:
y = np.arange(9).reshape(3,3)[:,:2]
y
Out[34]:
array([[0, 1],
[3, 4],
[6, 7]])
y.strides
Out[35]: (12, 4)
y.base
Out[36]: array([0, 1, 2, 3, 4, 5, 6, 7, 8])
y.flags
Out[37]:
C_CONTIGUOUS : False
F_CONTIGUOUS : False
OWNDATA : False
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False它是base值的不连续子集。base是原始的np.arange(...),而不是reshaped结果。
https://stackoverflow.com/questions/72294311
复制相似问题