以并行方式从数组中删除条目

时间:2016-07-13 16:44:47

标签: python arrays list numpy

我有一个x和y坐标的列表/数组,例如:

x = [x1, x2, x3,...]
y = [y1, y2, y3,...]

现在,我想根据条件删除某些条目,例如,以下内容:

for i in x:
    if i <= 40 and i >= -40:
        print "True"
    else:
        x.remove(i)

for i in y:
    if i <= 20 and i >=- 20:
        print "True"
    else:
        y.remove(i)

上面的代码会从列表中删除相应的条目,但如果x1被删除,y1仍会保留在列表中。我想要实现的是,如果删除x1,则还应删除y1。我该怎么做呢?我的最终目标是尝试绘制xy,因此我无法执行此操作,因为列表最终会有不同的维度。我也可以用

zeta_list = np.column_stack((x, y))

获取类似([[x1, y1], [x2, y2], [x3, y3],...]])的数组,但我不知道如何使用if条件从中删除条目。

感谢。

5 个答案:

答案 0 :(得分:4)

形成一个布尔选择掩码:

mask = ~((x > 40) | (x < -40) | (y > 20) | (y < -20))

然后,从xy选择mask为真的值:

x, y = x[mask], y[mask]

x是NumPy数组时,(x > 40)会返回与x形状相同的布尔数组True,其中x的元素为大于40。

请注意|用于按位 - 或~用于not(布尔否定)。

或者,通过De Morgan's law,您可以使用

mask = ((x <= 40) & (x >= -40) & (y <= 20) & (y >= -20))

NumPy操作以元素方式执行。因此,mask的元素在{-1}}的元素介于-40和40 之间且x的相应元素介于-20和20之间时才为真。

例如,

y

产量

import numpy as np
x = [-50, -50, 30, 0, 50]
y = [-30, 0, 10, 30, 40]

# change the lists to NumPy arrays
x, y = np.asarray(x), np.asarray(y)
# mask = ~((x > 40) | (x < -40) | (y > 20) | (y < -20))
mask = ((x <= 40) & (x >= -40) & (y <= 20) & (y >= -20))
x, y = x[mask], y[mask]

In [35]: x
Out[35]: array([30])

In [36]: y
Out[36]: array([10])

答案 1 :(得分:3)

另一种选择是使用list-comprehension

输入

x = [50, 10, -50, 30, 5, 6]
y = [2, 40, 10, 5, 3, 5]

代码

x, y = list(zip(*[(x, y) for x, y in zip(x, y) if x <= 40 and x > -40 and y <= 20 and y > -20]))

输出

x
# (30, 5, 6)

y
# (5, 3, 5)

答案 2 :(得分:3)

试试这个:

mask = ((x <= 40) & (x >= -40) & (y <= 20) & (y >= -20))
x, y = x[mask], y[mask]

NumPy将对这些操作进行矢量化,因此效率非常高。

This博文可能会有所帮助,这里有np.where()的手册,其中显示了一些类似的例子。

答案 3 :(得分:1)

这应该这样做。

for i in x1:
    if i <= 40 and i >= -40:
        print "True"
        for i in y1:
            if i <=20 and i >=-20:
                print "True"
            else:
                x1.remove(i)
                y1.remove(i)
    else:
        x1.remove(i)
        y1.remove(i)

希望这有帮助!

谢谢!

答案 4 :(得分:0)

为了完整起见,这是一个基于 itertools 的解决方案。

考虑以下坐标列表:

x = [-50, -50, -10,   0,  10, 50, 50, -10, -10, 0, 10, 40]
y = [-50, -20, -50,  50, -50, 20, 50, -20, -10, 0, 20, 10]

我们的目标是在Truen以某些间隔存在的那些索引x[n]中设置值为y[n]的布尔掩码,并{{ 1}}其他地方。时间间隔&#39;边界是:

False

我们可以通过列表理解创建这样的掩码:

xmin, xmax = -40, 40
ymin, ymax = -20, 20

对每对相应的坐标计算布尔表达式mask = [xmin <= i <= xmax and ymin <= j <= ymax for (i, j) in zip(x, y)] 。如果xmin <= i <= xmax and ymin <= j <= ymaxi都属于指定的时间间隔,则表达式将被评估为j,否则为True。比较可以在Python中链接的事实使得这个布尔表达式非常紧凑和可读。

最后,我们可以使用函数itertools.compress()摆脱那些超出限制的坐标对:

False

演示:

from itertools import compress
x_clipped = list(compress(x, mask))
y_clipped = list(compress(y, mask))