gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 05:14:44 25 4
gpt4 key购买 nike

我有两个不同大小的 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com