简体   繁体   English

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

[英]Finding X values in numpy array and substituting for random value

Consider an list of numpy arrays with values either -1's or 1's allocated in random positions.考虑一个 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])

I need to perform operations on these arrays like sum and point wise multiplication.我需要对这些数组执行操作,例如求和和逐点乘法。

For example, after summing 2 arrays i will have a new one with values -2,0 and 2.例如,在对 2 个数组求和后,我将得到一个值为 -2,0 和 2 的新数组。

c = a + b
c = [ 0 -2 2 0 0 2 -2 0 0 -2]

Now i would like to “normalize” it back to -1's and 1's.现在我想将它“规范化”回 -1 和 1。

For the 2's and -2's it is easy:对于 2 和 -2 来说,这很容易:

c[c < 0] = -1

c[c > 0] = 1

The problem is the 0. For them i would like to randomly choose either a -1 or a 1.问题是 0。对于他们,我想随机选择 -1 或 1。

The desired output would be like:所需的输出如下:

c =  [ 1 -1 1 -1 -1 1 -1 1 -1 -1]

In generalized terms my question is how to find all N values equal to x, in an array, then substitute each for a random number.概括地说,我的问题是如何在数组中找到等于 x 的所有 N 个值,然后将每个值替换为一个随机数。

My question is how to do this in the most “pythonic”, and fastest, way?我的问题是如何以最“pythonic”和最快的方式做到这一点?

Thank's谢谢

Just Posting the final results from the answers i got so far.只是发布我到目前为止得到的答案的最终结果。 If anyone in the future has a better solution please share it!如果将来有人有更好的解决方案,请分享它!

I timed the 3 solutions i found and one i did.我对我找到的 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)

The timings were:时间是:

%%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)

So as it stands it looks like answer 1 and 3 are the best ones.因此,目前看来答案13是最好的。 The difference between them looks minimal, but after trying some more runs the number 1 always come slightly on top .它们之间的差异看起来很小,但是在尝试更多次运行之后,数字 1 总是稍微领先

Thanks for the Helps guys!感谢各位大侠的帮助! I will add some references to HD computing in the question as this is a core problem in this application so it will be easier for someone to find it if needed.我将在问题中添加一些对高清计算的引用,因为这是此应用程序中的核心问题,因此如果需要,人们会更容易找到它。

I'm not in any way claiming this is the fastest nor most efficient approach.以任何方式声称这是最快的,也最有效的方法。

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)                                   

Result:结果:

In [64]: norm_arr                                                             
Out[64]: array([ 1, -1,  1,  1, -1,  1, -1,  1, -1, -1])

You might use:你可能会使用:

>>> 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])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM