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

2025-04-16 08:57:00
admin
原创
14
摘要:问题描述:下面是什么意思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大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

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

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

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用