当索引看起来像数字的内容时,Python 中的“三个点”是什么意思?

2025-04-16 08:57:00
admin
原创
53
摘要:问题描述:下面是什么意思x[...]?a = np.arange(6).reshape(2,3) for x in np.nditer(a, op_flags=['readwrite']): x[...] = 2 * x 解决方案 1:虽然建议的重复文章“Python 省略号对象有什么作用?”在一般情...

问题描述:

下面是什么意思x[...]

a = np.arange(6).reshape(2,3)
for x in np.nditer(a, op_flags=['readwrite']):
    x[...] = 2 * x

解决方案 1:

虽然建议的重复文章“Python 省略号对象有什么作用?”在一般情况下回答了这个问题,但我认为,在循环python中使用它需要添加信息。nditer

https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values

Python 中的常规赋值操作只是更改本地或全局变量字典中的引用,而不是直接修改现有变量。这意味着,简单地对 x 赋值并不会将值放入数组元素中,而是将 x 从数组元素引用切换为对所赋值的引用。要真正修改数组元素,应该使用省略号对 x 进行索引。

该部分包含您的代码示例。

所以用我的话来说,就地 x[...] = ...修改会破坏与变量的链接,而不是改变它。它类似于但适用于任何维度(包括 0 维)的数组。在这种情况下,它不仅仅是一个数字,而是一个数组。x`x = ...nditerx[:] = ...`x

nditer也许与此迭代最接近的nditer是:

In [667]: for i, x in np.ndenumerate(a):
     ...:     print(i, x)
     ...:     a[i] = 2 * x
     ...:     
(0, 0) 0
(0, 1) 1
...
(1, 2) 5
In [668]: a
Out[668]: 
array([[ 0,  2,  4],
       [ 6,  8, 10]])

请注意,我必须a[i]直接索引和修改。我不能使用x = 2*x。在这个迭代中,x它是一个标量,因此不可变。

In [669]: for i,x in np.ndenumerate(a):
     ...:     x[...] = 2 * x
  ...
TypeError: 'numpy.int32' object does not support item assignment

但在这种nditer情况下x是一个 0d 数组,并且可变。

In [671]: for x in np.nditer(a, op_flags=['readwrite']):
     ...:     print(x, type(x), x.shape)
     ...:     x[...] = 2 * x
     ...:     
0 <class 'numpy.ndarray'> ()
4 <class 'numpy.ndarray'> ()
...

因为它是 0d,所以x[:]不能用来代替x[...]

----> 3     x[:] = 2 * x
IndexError: too many indices for array

更简单的数组迭代也可能提供见解:

In [675]: for x in a:
     ...:     print(x, x.shape)
     ...:     x[:] = 2 * x
     ...:     
[ 0  8 16] (3,)
[24 32 40] (3,)

这将对的行(第一维)进行迭代ax然后是一维数组,可以使用x[:]=...或进行修改x[...]=...

如果我添加external_loop下一节中的标志,它x现在是一个一维数组,并且x[:] =可以正常工作。但x[...] =仍然有效,而且更通用。 x[...]所有其他nditer示例都使用了它。

In [677]: for x in np.nditer(a, op_flags=['readwrite'], flags=['external_loop']):
     ...:     print(x, type(x), x.shape)
     ...:     x[...] = 2 * x
[ 0 16 32 48 64 80] <class 'numpy.ndarray'> (6,)

比较这个简单的行迭代(在二维数组上):

In [675]: for x in a:
     ...:     print(x, x.shape)
     ...:     x[:] = 2 * x
     ...:     
[ 0  8 16] (3,)
[24 32 40] (3,)

这将对的行(第一维)进行迭代ax然后是一维数组,可以使用x[:] = ...或进行修改x[...] = ...

请通读本页并进行实验,nditer直至最后。 本身nditer在 中用处不大python。它不会加速迭代——除非你将代码移植到cythonnp.ndindex是少数numpy使用 的非编译函数之一nditer

解决方案 2:

省略号的...意思是as many : as needed

对于没有时间的人,这里有一个简单的例子:

In [64]: X = np.reshape(np.arange(9), (3,3))

In [67]: Y = np.reshape(np.arange(2*3*4), (2,3,4))

In [70]: X
Out[70]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [71]: X[:,0]
Out[71]: array([0, 3, 6])

In [72]: X[...,0]
Out[72]: array([0, 3, 6])

In [73]: Y
Out[73]:
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

In [74]: Y[:,0]
Out[74]:
array([[ 0,  1,  2,  3],
       [12, 13, 14, 15]])

In [75]: Y[...,0]
Out[75]:
array([[ 0,  4,  8],
       [12, 16, 20]])

In [76]: X[0,...,0]
Out[76]: array(0)

In [77]: Y[0,...,0]
Out[77]: array([0, 4, 8])

这使得每次只操作一个维度变得容易。

有一件事 - 在任何给定的索引表达式中只能有一个省略号,否则您的表达式对于:每个表达式中应该放入多少个省略号会产生歧义。

解决方案 3:

我相信一个很好的类比(大多数人可能已经习惯了)是这样的思考:

import numpy as np

random_array = np.random.rand(2, 2, 2, 2)

这样的情况下,[:, :, :, 0] and [..., 0]都是一样的。

你可以用它来分析特定的维度,比如你有一批 50 个 128x128 RGB 图像(50,3,128,128),如果你想在每个颜色通道的每个图像中切出一块,你可以这样做image[:,:,50:70, 20:80] or image[...,50:70,20:80]

请注意,您不能在语句中多次使用它,因为这[...,0,...]是无效的。

解决方案 4:

无需长篇解释:-) 在 Numpy 中,省略号(3 个点)仅表示“索引与数组形状匹配所需的数量:” 。

:本身是表示所考虑维度中所有元素的快捷方式。


例如,对于一个形状(n, p, q, r, s),即一个具有 5 个维度的数组,可以使用省略号来替换 0、1、2、3、4 或 5 个连续的:。这些形式是等效的:

  • a[:, :, :, 4, 2]a[..., 4, 2]

  • a[4, :, :, :, 2]a[4, ..., 2]

  • a[4, 2, :, :, :]a[4, 2, ...]

  • a[:, :, :, :, 4]a[..., 4]

  • a[:, :, :, :, :]a[...]

以及任何带有如下切片的变体:

  • a[1:2, :, :, :, 2:6]a[1:2, ..., 2:6]

这可以用来简化返回数组切片的索引,而不是使用连续的索引:来包含相应的整个维度。这种简化隐藏了数组的实际形状,并可能导致切片错误。

确实,索引中只能有一个省略号,否则 Numpy 如何知道如何分配所需的省略号:

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3949  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2735  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   74  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   82  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   68  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用