python - 根据不同大小的数组 Y 的条件屏蔽数组 X

标签 python arrays numpy array-broadcasting

我有两个不同大小的 1-dim 数组 XY。我正在尝试构建由 XY 条件产生的 2-dim 数组。例如:

X = np.array([0.3, 2.1, 4.3])
Y = np.array([1.5, 3.5])
mask = X > Y[:,np.newaxis]

现在我想执行类似于 X[mask] = X[mask] + 1 的操作,因此对于上面的示例,它会导致:

newX = np.array([0.3, 3.1, 5.3],[0.3, 2.1, 5.3]])

我通过以下方式获得了这个结果:

newX = np.append(X, X).reshape(2,3)
newX[mask]=newX[mask]+1

但这硬编码了 Y 数组的长度(示例中为 2),并包含一个带有 np.append 的副本,这在 XY 实际上是大型数组(而且它可能也很丑陋)。有正确的方法吗?

最佳答案

在这种特殊情况下,您希望在 mask 为 True 时加 1, 也许最简单的方法是利用广播和 dtype 提升——也就是说, bool 值在数字上下文中被视为整数。

In [49]: X + mask
Out[49]: 
array([[ 0.3,  3.1,  5.3],
       [ 0.3,  2.1,  5.3]])

如果可能,使用广播代替 X 的显式平铺副本。 但是,如果您需要 newX,您可以使用

In [54]: np.tile(X, (Y.size,1))
Out[54]: 
array([[ 0.3,  2.1,  4.3],
       [ 0.3,  2.1,  4.3]])

np.tile避免了由 np.outer 完成的乘法运算,因此速度更快。


例如,使用此设置:

import numpy as np
import timeit 
import collections
import matplotlib.pyplot as plt

timing = collections.defaultdict(list)
Ns = np.linspace(10, 10000, 5).astype(int)
Ms = np.linspace(10, 10000, 5).astype(int)

for N, M in zip(Ns, Ms):
    X = np.random.random(N)
    Y = np.random.random(M)
    timing['tile'].append(timeit.timeit(
        'np.tile(X, (Y.size,1))',
        'from __main__ import np, X, Y',
        number=10))
    timing['outer'].append(timeit.timeit(
        'np.outer(np.ones_like(Y),X)',
        'from __main__ import np, X, Y',
        number=10))


plt.plot(Ns*Ms, timing['tile'], label='tile')
plt.plot(Ns*Ms, timing['outer'], label='outer')
plt.legend(loc='best')
plt.show()

enter image description here

随着数组的大小变大,tileouter 之间的区别 应该相对于总时间减少,因为 在 RAM 中分配/管理大型数组/交换淹没了相对较小的数组 计算成本。

关于python - 根据不同大小的数组 Y 的条件屏蔽数组 X,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42065007/

相关文章:

python - 加入两个数据框并扩展其中一个的内容

python - 使用 python 将 Opencv Mat 转储到 YAML 文件中

java - 有 Intent 地在 2 个 Activity 之间传递数组

php - Silverstripe - 检索数组中的 POST 数组

arrays - 为什么字节 slice 的元素在 Go 中以整数形式返回?

Python极坐标图;给定数据集的每个点使用不同的颜色

python - 在 pandas 中,如何从字典列表创建数据框?

python - PuLP LP 最小化配方 "Select one type"约束

python - 在不知道各个维度的情况下访问多维数组的每个元素

python - Matplotlib:如何绘制列表中的数据,添加两个 y 轴?