【问题标题】:How to use numpy where on each element of test array without a for-loop?如何在没有for循环的情况下在测试数组的每个元素上使用numpy where?
【发布时间】:2019-06-15 10:26:13
【问题描述】:

我想在例程中使用 numpy 函数而不使用 for 循环。考虑下面的例子:

import numpy as np

data = np.linspace(1, 10, 10).astype(int) 
test_elements = np.array([1, 2])
for test_elem in test_elements:
    print(np.where(test_elem == data))

...

(array([0]),)
(array([1]),)

我已阅读其他帖子和 numpy 文档。常见的建议似乎是使用np.roll 滚动test_elements,或者使用其他技巧,例如跨步(我不完全理解)。我认为使用np.vectorize 对函数进行矢量化可能更容易,但我觉得这对于一个问题来说太过分了,必须有一个更简单的解决方案。任何指导将不胜感激?

【问题讨论】:

  • 嗯...您的data 没有重复项吗?否则where 的返回值可以是不同的长度(我猜即使在这里它也可以有不同的长度,好像test_elem 不存在,结果会是空的),并且numpy 不擅长处理可变长度的东西。
  • 在上面的例子中,它们都是唯一的。那只是因为我试图让问题变得简单。如果有重复条目,我计划在最后连接唯一元素。
  • 更快的方法取决于您的实际数据的大小,以及您想对结果做什么。请记住,只有当data 的大小很小(而test_elements 的大小很大)时,for 循环才会真正低效。

标签: python-3.x numpy for-loop vectorization where


【解决方案1】:

这是使用.outernp.split 的一种方法,我让这个例子更有趣了。

data = np.linspace(1, 5, 10).astype(int) 
test_elements = np.array([1, 2, 4, 6])
y, x = np.where(np.equal.outer(test_elements,data))
np.split(x, y.searchsorted(np.arange(1,test_elements.size)))
# [array([0, 1, 2]), array([3, 4]), array([7, 8]), array([], dtype=int64)]

一些解释:

np.equal.outer(test_elements,data)

相同
 test.elements[:,None] == data[None,:]

所以这是一个二维布尔数组,其行等于你的 for 循环中出现的布尔数组 test_elem == data

where 从这里返回两个索引数组,每个坐标一个。 x 是快速变化的坐标,等于 for 循环返回的 1d where 的值,但它们都粘在一起形成一个长向量。 y 是慢变换坐标,它的值是有序的,可以用来分组/拆分xsearchsorted 可能不是最有效的方法,但它很简单并且可以正确处理空行。

【讨论】:

  • 我知道这行得通。但是你能解释一点逻辑吗?据我了解,.equal 用于检查有序相等,.outer 用于广播这些布尔值,.searchsorted 用于指定哪些值进入哪些箱(如在直方图中)。但我不完全理解您的解决方案是如何工作的。
  • @allthemikeysaretaken 添加了一些解释。
猜你喜欢
  • 2021-01-29
  • 2017-03-25
  • 2022-01-12
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2013-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多