在 numpy 数组中查找 X 值并替换为随机值
Finding X values in numpy array and substituting for random value
考虑一个 numpy 数组列表,其值是 -1 或 1,随机分配。
a = np.array([1,-1,1,1,-1,1,-1,-1,1,-1])
b = np.array([-1,-1,1,-1,1,1,-1,1,-1,-1])
我需要对这些数组执行运算,例如求和和逐点乘法。
例如,在对 2 个数组求和后,我将得到一个值为 -2,0 和 2 的新数组。
c = a + b
c = [ 0 -2 2 0 0 2 -2 0 0 -2]
现在我想将它“标准化”回-1 和 1。
对于 2 和 -2 很简单:
c[c < 0] = -1
c[c > 0] = 1
问题是 0。对于他们,我想随机选择 -1 或 1。
所需的输出如下:
c = [ 1 -1 1 -1 -1 1 -1 1 -1 -1]
笼统地说,我的问题是如何在数组中找到所有等于 x 的 N 个值,然后用每个值替换一个随机数。
我的问题是如何以最“pythonic”和最快的方式做到这一点?
谢谢
我不以任何方式声称这是最快也最有效的方法。
c = np.array([ 0, -2, 2, 0, 0, 2, -2, 0, 0, -2])
def norm(a):
if a == 0:
return np.random.choice(np.array([-1,1]))
else:
return a / a * np.sign(a)
v_norm = np.vectorize(norm)
norm_arr = v_norm(c)
结果:
In [64]: norm_arr
Out[64]: array([ 1, -1, 1, 1, -1, 1, -1, 1, -1, -1])
您可能会使用:
>>> c = [0, -2, 2, 0, 0, 2, -2, 0, 0, -2]
>>> c = np.array([0, -2, 2, 0, 0, 2, -2, 0, 0, -2])
>>> zind = np.where(c==0)[0]
>>> c[zind] = np.array([np.random.choice([1, -1]) for _ in zind])
>>> c
array([ 1, -2, 2, -1, -1, 2, -2, -1, 1, -2])
只是发布我目前得到的答案的最终结果。
以后有谁有更好的解决办法欢迎分享!
我对我找到的 3 个解决方案和一个我做过的解决方案进行了计时。
def Norm1(HV):
HV[HV > 0] = 1
HV[HV < 0] = -1
zind = np.where(HV == 0)[0]
HV[zind] = np.array([np.random.choice([1, -1]) for _ in zind])
return HV
def norm2(HV):
if HV == 0:
return np.random.choice(np.array([-1,1]))
else:
return HV / HV * np.sign(HV)
Norm2 = np.vectorize(norm2)
def Norm3(HV):
HV[HV > 0] = 1
HV[HV < 0] = -1
mask = HV==0;
HV[mask] = np.random.choice((-1,1),HV[mask].shape)
return HV
def generate(size):
return np.random.binomial(1, 0.5, size=size) * 2 - 1
def Norm4(arr):
np.floor_divide(arr, 2, out=arr)
positions = (arr == 0)
size = sum(positions)
np.add.at(arr, positions, generate(size)
时间是:
%%timeit
d = Norm1(c)
203 µs ± 5.9 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
d = Norm2(c)
33.4 ms ± 1.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
d = Norm3(c)
217 µs ± 11.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
d = Norm4(c)
21 ms ± 1.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
所以目前看起来答案 1 和 3 是最好的答案。它们之间的差异看起来很小,但在尝试更多运行后,数字 1 总是略微位于顶部。
感谢大家的帮助!
我将在问题中添加一些对 HD 计算的引用,因为这是此应用程序中的核心问题,因此如果需要,人们可以更轻松地找到它。
考虑一个 numpy 数组列表,其值是 -1 或 1,随机分配。
a = np.array([1,-1,1,1,-1,1,-1,-1,1,-1])
b = np.array([-1,-1,1,-1,1,1,-1,1,-1,-1])
我需要对这些数组执行运算,例如求和和逐点乘法。
例如,在对 2 个数组求和后,我将得到一个值为 -2,0 和 2 的新数组。
c = a + b
c = [ 0 -2 2 0 0 2 -2 0 0 -2]
现在我想将它“标准化”回-1 和 1。
对于 2 和 -2 很简单:
c[c < 0] = -1
c[c > 0] = 1
问题是 0。对于他们,我想随机选择 -1 或 1。
所需的输出如下:
c = [ 1 -1 1 -1 -1 1 -1 1 -1 -1]
笼统地说,我的问题是如何在数组中找到所有等于 x 的 N 个值,然后用每个值替换一个随机数。
我的问题是如何以最“pythonic”和最快的方式做到这一点?
谢谢
我不以任何方式声称这是最快也最有效的方法。
c = np.array([ 0, -2, 2, 0, 0, 2, -2, 0, 0, -2])
def norm(a):
if a == 0:
return np.random.choice(np.array([-1,1]))
else:
return a / a * np.sign(a)
v_norm = np.vectorize(norm)
norm_arr = v_norm(c)
结果:
In [64]: norm_arr
Out[64]: array([ 1, -1, 1, 1, -1, 1, -1, 1, -1, -1])
您可能会使用:
>>> c = [0, -2, 2, 0, 0, 2, -2, 0, 0, -2]
>>> c = np.array([0, -2, 2, 0, 0, 2, -2, 0, 0, -2])
>>> zind = np.where(c==0)[0]
>>> c[zind] = np.array([np.random.choice([1, -1]) for _ in zind])
>>> c
array([ 1, -2, 2, -1, -1, 2, -2, -1, 1, -2])
只是发布我目前得到的答案的最终结果。 以后有谁有更好的解决办法欢迎分享!
我对我找到的 3 个解决方案和一个我做过的解决方案进行了计时。
def Norm1(HV):
HV[HV > 0] = 1
HV[HV < 0] = -1
zind = np.where(HV == 0)[0]
HV[zind] = np.array([np.random.choice([1, -1]) for _ in zind])
return HV
def norm2(HV):
if HV == 0:
return np.random.choice(np.array([-1,1]))
else:
return HV / HV * np.sign(HV)
Norm2 = np.vectorize(norm2)
def Norm3(HV):
HV[HV > 0] = 1
HV[HV < 0] = -1
mask = HV==0;
HV[mask] = np.random.choice((-1,1),HV[mask].shape)
return HV
def generate(size):
return np.random.binomial(1, 0.5, size=size) * 2 - 1
def Norm4(arr):
np.floor_divide(arr, 2, out=arr)
positions = (arr == 0)
size = sum(positions)
np.add.at(arr, positions, generate(size)
时间是:
%%timeit
d = Norm1(c)
203 µs ± 5.9 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit
d = Norm2(c)
33.4 ms ± 1.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
d = Norm3(c)
217 µs ± 11.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
d = Norm4(c)
21 ms ± 1.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
所以目前看起来答案 1 和 3 是最好的答案。它们之间的差异看起来很小,但在尝试更多运行后,数字 1 总是略微位于顶部。
感谢大家的帮助! 我将在问题中添加一些对 HD 计算的引用,因为这是此应用程序中的核心问题,因此如果需要,人们可以更轻松地找到它。