numpy.ndarray.flags.contiguous是什么意思?

zynd9foi  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(144)

在使用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 = }
''')

根据有关memoryview类的文档,如果数组是C连续的或Fortran连续的,则data.contiguous == True。至于numpy.info,我相信它显示了flags.contiguous的值。可惜的是,在the manual中没有关于它的信息。它实际上意味着什么?是flags.c_contiguous的同义词吗?

e4eetjau

e4eetjau1#

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作为数组的连续性参数。这一个在flags description中没有指定。但是我们可以在flagsobject.c中找到它:

// ...
static PyGetSetDef arrayflags_getsets[] = {
    {"contiguous",
        (getter)arrayflags_contiguous_get,
        NULL,
        NULL, NULL},
    {"c_contiguous",
        (getter)arrayflags_contiguous_get,
        NULL,
        NULL, NULL},
// ...

所以现在很清楚,来自numpy.infocontiguous参数实际上是flags.c_contiguous,与ndarray.data.contiguous没有任何共同之处。我想在C语言中编程时,很自然地只说contiguous而不是c_contiguous,这导致了术语上的轻微不一致。

ogq8wdun

ogq8wdun2#

x = np.arange(9).reshape(3,3)[:,(0,1)]

np.arange(9)生成一个一维数组; reshape(3,3)将其重塑为2d。它是原始arangeview。如果没有order参数,reshape将使用默认的c-order
[0,[0,1]]是高级索引,制作副本。使用[0,:2]索引将选择相同的值,但生成view
info步长为(8,24)。整形后xstrides应该是(24,8),最后一个维度步进8个字节,第一个维度步进3*8。但是高级索引会把事情颠倒过来--这是我们通常忽略(或不知道)的索引细节。
第一个跨距较小的二维数组是F-order
我不会试图破译所有的数据/单位连续打印,但基本布局是显而易见的,我从形状和步伐。我认为步幅有优先权,所有的“连续”显示都是衍生的,可以说是对步幅的解释。
对于3d(或更高)阵列,contiguous替代品可能会崩溃。可以用(48,8,24)这样的步幅来创建数组,其中中间维度的步幅最快。既不是C也不是F。
我可能会补充说,除非你正在做的事情,

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是False?显然,索引实际上创造了:

x.base
Out[32]: 
array([[0, 3, 6],
       [1, 4, 7]])

然后返回转置。c_contiguous数组的转置是f_contiguous。
如果我创建相同的数组(按值),但使用切片,我会得到一个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的结果。

carvr3hs

carvr3hs3#

若要修复此错误

AttributeError: 'Flags' object has no attribute 'c_contiguous'

只需对代码进行一些更改,如下所示:

y_train_predict = KNN_model.predict(X_train.values) # add .values to the X_train
model_score = KNN_model.score(X_train.values, y_train) # add .values to the X_train

不需要升级你的sklearn版本。只需添加.values

相关问题