逐元素布尔乘法

时间:2018-08-09 01:03:49

标签: python numpy

我正在寻找一种最漂亮,最短的方法来增加这些类型的列表:

a = [True, False, True, False, False]

b = [100, 200]

b 的长度等于 a

中True元素的数量

我需要的答案是[100, 0, 200, 0, 0]在这里

有没有简单的方法来获得答案?
看起来像逐元素乘法,但事实是第二个列表的大小较小,因此常见的numpy方法在没有错误代码的情况下无法工作。

希望,您会找到很好的解决方案

4 个答案:

答案 0 :(得分:8)

您可以在numpy中进行此操作:

c = np.array(a).astype(int)

c[c==1] = b

>>> c
array([100,   0, 200,   0,   0])

注意:如果需要将结果作为列表(基于所需的输出)而不是numpy数组,请使用c.tolist()

答案 1 :(得分:7)

有一个非常干净的基于迭代器的解决方案

it = iter(b)
[next(it) if x else 0 for x in a]
# [100, 0, 200, 0, 0]

答案 2 :(得分:2)

另一种选择是使用numpy.place()numpy.put()

c = np.zeros_like(a, dtype=np.result_type(b))
np.place(c, a, b)

c = np.zeros_like(a, dtype=np.result_type(b))
np.put(c, np.flatnonzero(a), b)

我更喜欢第一种选择。

时间:

生成更大的数据集:

In [39]: a = np.random.randint(0, 2, 100000).astype(np.bool_)

In [40]: b = np.random.randint(0, 100000, np.sum(a))

@sacul解决方案:

In [41]: %timeit c = np.array(a).astype(int); c[c==1] = b
621 µs ± 13.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

我的第一个选择:

In [42]: %timeit c = np.zeros_like(a, dtype=np.result_type(b)); np.place(c, a, b)
462 µs ± 8.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

答案 3 :(得分:1)

从上面的@AGN滑动一下

c = np.zeros_like(a, dtype = b.dtype)
c[a] = b