Python 在numpy数组中查找X值并替换随机值

Python 在numpy数组中查找X值并替换随机值,python,arrays,numpy,vectorization,Python,Arrays,Numpy,Vectorization,考虑一个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 &

考虑一个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
一般来说,我的问题是如何在一个数组中找到所有等于x的N值,然后用每个值替换一个随机数

我的问题是如何以最“蟒蛇式”和最快的方式做到这一点

谢谢

我并不是说这是最快也最有效的方法

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)
因此,从目前的情况来看,答案13似乎是最好的答案。它们之间的差别看起来很小,但是在尝试了更多的跑步之后,第一名总是稍微领先一点

谢谢你们的帮助!
我将在这个问题中添加一些关于HD计算的参考,因为这是这个应用程序中的一个核心问题,所以如果需要的话,人们会更容易找到它

请给出一个输入数组、中间步骤和预期输出的示例。嘿!谢谢我试图举例说明这个问题<代码>掩码=c==0;一个[mask]=np.random.choice(-1,1),一个[mask].shape)看起来这个可能非常快!谢谢将尝试与其他想法进行对比,看看每个想法如何运行。您好!谢谢你的主意!我会试试这个,并将它的性能与其他解决方案进行比较。好的,不客气。完成后,请发布一个带有计时结果的答案!
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)