【问题标题】:Replacing entire elements in an array替换数组中的整个元素
【发布时间】:2021-11-14 16:11:50
【问题描述】:

问题 假设我有以下数组tile1

[[80 80 80]
  [80 80 80]
  [80 80 80]
  [80 80 80]]

我想用数组[1 5 10] 替换每个[80 80 80] 元素。我该怎么做?

我的尝试

我试过了

print(tile1==[80,80,80])

我认为这非常有用,但后来我意识到这是一样的

print(tile1==80)

所以当我尝试

tile1[tile1==[80,80,80]]=[1,5,10]

当然失败了。我只能根据tile1[tile1==[80,80,80]]=5等基本元素分配值

【问题讨论】:

标签: python numpy


【解决方案1】:

这些不是“整个元素”,它们是称为行的内存条。 Numpy 数组不像列表。列表存储对嵌套元素的引用。 Numpy arrays 是内存块。形状和切片表示具有不同步幅的视图,而不是多层间接。

您可以使用broadcasting 分配给切片。在这种情况下,您需要指定一个索引,用布尔值标记包含您想要的元素的所有行,并告诉索引填充所有列。

您的替换数组将正确广播到列。但是,让我们看一下索引。

tile1 == 80

由于广播,这会导致与tile1 形状相同的数组。 == 进行元素比较。这也是:

tile1 == [80, 80, 80]

那么如何为每一行而不是每个元素获取一个布尔值?您沿相应的轴使用np.all

np.all(tile1 == 80, axis=1)

或者我喜欢使用方法版本来表达它:

(tile1 == 80).all(axis=1)

就是这样。生成的掩码与 tile1 的行数一样多,因此您可以像以前一样直接使用它:

tile1[(tile1 == 80).any(1)] = [1, 5, 10]

之所以有效,是因为当您省略尾随索引时,它们会隐式设置为 :...。这是basic indexing 的标准功能。您正在将 3 元素序列分配给 (n, 3) 形索引。 n由掩码中True元素的个数决定,3tile1的剩余维度的形状。

【讨论】:

  • 谢谢!您的解释很有帮助并解决了我的问题,尽管我不能说我完全理解它。出于某种原因,numpy 的索引对我来说很难掌握。我会再次仔细阅读您的答案并转到链接。如果您知道其他资源来理解这一点,我将不胜感激
  • @KansaiRobot。我已经链接到几个页面,这将有所帮助。确实,最好的方法是在阅读文档时使用示例。我只是通过实践很好地理解了这些东西。 scipy-lectures.org/intro/numpy/operations.html 之类的东西也可能有帮助。
【解决方案2】:

这可能有效,但需要进行一些测试,我只是检查所有列的值是否相同。在这个例子中它的80

arr = array([[80, 80, 80],
       [80, 80, 80],
       [80, 80, 80],
       [80, 80, 80]])

arr[arr.all(1)] = [1, 5, 10]

array([[ 1,  5, 10],
       [ 1,  5, 10],
       [ 1,  5, 10],
       [ 1,  5, 10]])

【讨论】:

  • 这与我的答案相同,但没有任何解释性材料
  • 哦,对不起,我想我们同时发布了我们的答案,我没有看到你的
猜你喜欢
  • 2018-12-21
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 2015-11-09
  • 1970-01-01
  • 2020-09-21
  • 2019-12-20
  • 2018-11-06
相关资源
最近更新 更多