【问题标题】:Select elements within certain range per column in a 2D NumPy array在 2D NumPy 数组中选择每列特定范围内的元素
【发布时间】:2016-12-23 13:27:03
【问题描述】:

我有一个 2D NumPy 数组,其中包含如下元素:

[[-10,  0]
 [-9,   1]
 [ 9,  -5]
 [-8,   6]
 [-7,  -5]
 [-7,  -6]
 [ 0, -10]]

我想只存储那些满足以下条件的元素:

  1. 第一列的值在范围内:-10 <= x <= 0

和

  1. 第二列的值在范围内:-9 <= y <= 1

选择后的数组应如下所示:

[[-10,  0]
 [-9,   1]     
 [-7,  -6]
 [-7,  -5]]

【问题讨论】:

  • 查看np.logical_and()。
  • @Divakar 我如何将它用于二维数组?有没有一种方法我不必将 2d 数组拆分为 2 个数组然后应用 logical_and() ?
  • 您不需要拆分,只需切片:a[:,0] 和 a[:,1]。
  • @Divakar 限制对于 x 和 y 来说是不同的,我只是为了这个例子而把它们放在一起。我将在问题中对其进行编辑。
  • 对 col0 使用 (a[:,0]>=-10) & (a[:,0]<=0),对 col1 使用类似的限制,然后对这两个掩码执行 AND 并使用布尔索引选择带有 [mask] 的 a 之外的行。跨度>

标签: python arrays performance numpy


【解决方案1】:

这是一种矢量化方法 -

In [78]: a   # Input array
Out[78]: 
array([[-10,   0],
       [ -9,   1],
       [  9,  -5],
       [ -8,   6],
       [ -7,  -5],
       [ -7,  -6],
       [  0, -10]])

In [79]: col0m = (a[:,0]>=-10) & (a[:,0]<=0) # Column-0 mask

In [80]: col1m = (a[:,1]>=-9) & (a[:,1]<=1) # Column-1 mask

In [81]: a[col0m & col1m] # AND of masks and then index into input array
Out[81]: 
array([[-10,   0],
       [ -9,   1],
       [ -7,  -5],
       [ -7,  -6]])

另一种方法-

In [99]: a    # Input array
Out[99]: 
array([[-10,   0],
       [ -9,   1],
       [  9,  -5],
       [ -8,   6],
       [ -7,  -5],
       [ -7,  -6],
       [  0, -10]])

In [100]: a[((a >= [-10, -9]) & (a <=[0, 1])).all(1)]
Out[100]: 
array([[-10,   0],
       [ -9,   1],
       [ -7,  -5],
       [ -7,  -6]])

【讨论】:

  • 这比之前提出的方法还要好! 数组大小 = 600 个元素的平均执行时间:previous approach = 0.000411225449045current approach = 0.000109511125017。很好的答案!谢谢:D
  • 矢量化的方法比第二种方法略好。第二个的平均执行时间约为0.000142266684732。伙计,你真的知道你的东西吗?! :D
  • @hulkinBrain 你的意思是第二种方法a[((a &gt;= [-10, -9]) &amp; (a &lt;=[0, 1])).all(1)] 比第一种更好,对吧?
  • 不,矢量化的比a[((a &gt;= [-10, -9]) &amp; (a &lt;=[0, 1])).all(1)]好。尝试了 array size = 1200 的两种方法,矢量化比第二种方法有相当大的优势。 vectorized method: 0.0002024000257022nd approach: 0.000357377823159
  • @hulkinBrain 啊,是的,第一个是内存效率高的,因为它创建 1D 掩码而不是 2D 掩码,就像第二种方法一样,因此第一种方法的好处。不错!
【解决方案2】:

一个简单的迭代方法是:

data = [[-10,  0],
 [-9,   1],
 [ 9,  -5],
 [-8,   6],
 [-7,  -5],
 [-7,  -6],
 [ 0, -10]]

final = []
for outer_values in data:
    if -10 <= outer_values[0] <= 0 and  -9 <= outer_values[1] <= 1:
        final.append(outer_values)

输出:

[[-10, 0], [-9, 1], [-7, -5], [-7, -6]]

【讨论】:

  • 是的,这太完美了!但我必须让@Divakar 占优势。该方法的执行速度比此方法稍快。我的计算将在云端实时完成,所以时间至关重要。接受我的投票 :D 谢谢伙计!这个的执行时间是:0.000515149271765s,他的方法是:0.000367504808572
  • 是的,没问题。谢谢:)
【解决方案3】:

另一种方法是使用列表推导:

 data = [[-10,  0],
 [-9,   1],
 [ 9,  -5],
 [-8,   6],
 [-7,  -5],
 [-7,  -6],
 [ 0, -10]]

[x for x in data if -10 <= x[0] <= 0 and -9 <= x[1] <=1]

【讨论】:

  • 是的,这也很好!但它的平均执行时间是:0.000490425459102s。 Divakar 的方法仍然更快。不过请接受我的投票!谢谢:D
猜你喜欢
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 2019-12-18
  • 2011-04-01
  • 2018-08-10
  • 1970-01-01
  • 2018-12-03
  • 2021-10-06
相关资源
最近更新 更多