Python TypeError:迭代器操作数或请求的数据类型保留引用

Python TypeError:迭代器操作数或请求的数据类型保留引用,python,arrays,numpy,Python,Arrays,Numpy,Python新手。我在使用numpy的时候遇到了nditer(),它迭代多维数组以获得标量。我有点搞不清楚它是如何工作或行为的。 arr2 = np.array([[1, 2, 3],[4, 5, 6]]) for x in np.nditer(arr2): print(x,end=" ") 它发出123456 但是,如果我更改其中一个数组中的元素数,它将抛出一个错误 arr2 = np.array([[1, 2, 3],[4, 5, 6, 7]]) for x i

Python新手。我在使用numpy的时候遇到了nditer(),它迭代多维数组以获得标量。我有点搞不清楚它是如何工作或行为的。

arr2 = np.array([[1, 2, 3],[4, 5, 6]])
for x in np.nditer(arr2):
    print(x,end=" ")
它发出123456
但是,如果我更改其中一个数组中的元素数,它将抛出一个错误

arr2 = np.array([[1, 2, 3],[4, 5, 6, 7]])
for x in np.nditer(arr2):
    print(x,end=" ")
TypeError:迭代器操作数或请求的数据类型保留引用,但未启用REFS\u OK标志


我做错了什么,或者nditer()只适用于规则形状的数组?是否有任何方法可以从形状不规则的数据阵列中获取标量值(当然不用于循环)?

您可以使用以下方法展平数据阵列:

arr2.sum()
# Result will be: [1, 2, 3, 4, 5, 6, 7]
然后可以继续在单个for循环中获取标量值


更详细的说明。

您可以使用以下方法展平数据阵列:

arr2.sum()
# Result will be: [1, 2, 3, 4, 5, 6, 7]
然后可以继续在单个for循环中获取标量值


更详细的解释。

不同之处在于,当您声明
arr2=np.array([[1,2,3],[4,5,6,7]])
时,结果不是结构化数据,它将被指定为包含列表的object类型数组:

array([list([1, 2, 3]), list([4,5,6,7])], dtype=object)
当您输入结构化数据时,输出将是一个具有输入类型(int64、float64等)和相应维度的数组

如果您有一组大小不同的列表,最好的解决方案是创建一个包含所有元素的列表并对其进行迭代。如果你想坚持使用numpy,你可以做
np.concatenate([[1,2,3],[4,5,6,7])
,这将返回一个维度1的平坦数组,你也可以迭代它

import numpy as np

arr2 = np.concatenate([[1, 2, 3],[4, 5, 6, 7]])
for x in np.nditer(arr2):
    print(x,end=" ")

不同之处在于,当您声明
arr2=np.array([[1,2,3],[4,5,6,7]])
时,结果不是结构化数据,它将被指定为包含列表的object类型的数组:

array([list([1, 2, 3]), list([4,5,6,7])], dtype=object)
当您输入结构化数据时,输出将是一个具有输入类型(int64、float64等)和相应维度的数组

如果您有一组大小不同的列表,最好的解决方案是创建一个包含所有元素的列表并对其进行迭代。如果你想坚持使用numpy,你可以做
np.concatenate([[1,2,3],[4,5,6,7])
,这将返回一个维度1的平坦数组,你也可以迭代它

import numpy as np

arr2 = np.concatenate([[1, 2, 3],[4, 5, 6, 7]])
for x in np.nditer(arr2):
    print(x,end=" ")

第一种情况产生一个二维数字数组:

In [1]: arr = np.array([[1,2,3],[4,5,6]])
In [2]: arr
Out[2]: 
array([[1, 2, 3],
       [4, 5, 6]])
In [3]: arr.shape
Out[3]: (2, 3)
您可以轻松地重塑这样的阵列:

In [4]: arr.ravel()
Out[4]: array([1, 2, 3, 4, 5, 6])
像这样的整个数组操作比循环或另一个(隐藏的)迭代(在Python代码中)更受欢迎

第二种情况不产生二维阵列:

In [5]: arr2 = np.array([[1,2,3],[4,5,6,7]])
<ipython-input-5-4a78eda0f1a8>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  arr2 = np.array([[1,2,3],[4,5,6,7]])
In [6]: arr2 = np.array([[1,2,3],[4,5,6,7]], object)
In [7]: arr2
Out[7]: array([list([1, 2, 3]), list([4, 5, 6, 7])], dtype=object)
In [8]: arr2.shape
Out[8]: (2,)
我们不需要对这样的列表使用
numpy

In [10]: alist = [[1,2,3],[4,5,6,7]]
In [12]: [i for j in alist for i in j]
Out[12]: [1, 2, 3, 4, 5, 6, 7]
===

np.nditer
需要更强的免责声明。最好将其视为编写编译代码的桥梁(使用
cython
),而不是Python代码中的主要工具。它不会提高速度或避免“循环”。有很多可能有用,但只会让初学者感到困惑的东西

In [13]: for x in np.nditer(arr):
    ...:     print(x, x.shape, type(x))
    ...: 
1 () <class 'numpy.ndarray'>
2 () <class 'numpy.ndarray'>
3 () <class 'numpy.ndarray'>
4 () <class 'numpy.ndarray'>
5 () <class 'numpy.ndarray'>
6 () <class 'numpy.ndarray'>

与前面一样,
x
是一个0d数组,只有在这种情况下,该数组的元素是一个对象,一个列表。因此,如果您的目标是展开迭代,则这没有帮助。

第一种情况产生一个二维数字数组:

In [1]: arr = np.array([[1,2,3],[4,5,6]])
In [2]: arr
Out[2]: 
array([[1, 2, 3],
       [4, 5, 6]])
In [3]: arr.shape
Out[3]: (2, 3)
您可以轻松地重塑这样的阵列:

In [4]: arr.ravel()
Out[4]: array([1, 2, 3, 4, 5, 6])
像这样的整个数组操作比循环或另一个(隐藏的)迭代(在Python代码中)更受欢迎

第二种情况不产生二维阵列:

In [5]: arr2 = np.array([[1,2,3],[4,5,6,7]])
<ipython-input-5-4a78eda0f1a8>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  arr2 = np.array([[1,2,3],[4,5,6,7]])
In [6]: arr2 = np.array([[1,2,3],[4,5,6,7]], object)
In [7]: arr2
Out[7]: array([list([1, 2, 3]), list([4, 5, 6, 7])], dtype=object)
In [8]: arr2.shape
Out[8]: (2,)
我们不需要对这样的列表使用
numpy

In [10]: alist = [[1,2,3],[4,5,6,7]]
In [12]: [i for j in alist for i in j]
Out[12]: [1, 2, 3, 4, 5, 6, 7]
===

np.nditer
需要更强的免责声明。最好将其视为编写编译代码的桥梁(使用
cython
),而不是Python代码中的主要工具。它不会提高速度或避免“循环”。有很多可能有用,但只会让初学者感到困惑的东西

In [13]: for x in np.nditer(arr):
    ...:     print(x, x.shape, type(x))
    ...: 
1 () <class 'numpy.ndarray'>
2 () <class 'numpy.ndarray'>
3 () <class 'numpy.ndarray'>
4 () <class 'numpy.ndarray'>
5 () <class 'numpy.ndarray'>
6 () <class 'numpy.ndarray'>

与前面一样,
x
是一个0d数组,只有在这种情况下,该数组的元素是一个对象,一个列表。因此,如果您的目标是扁平化迭代,那么这并没有帮助。

不要为
nditer
而烦恼。它通常是不需要的,而且会让初学者感到困惑。尽量避免在数组上进行迭代。不要麻烦使用
nditer
。它通常是不需要的,而且会让初学者感到困惑。尽量避免在数组上进行迭代。