2017-02-28 24 views
2

numpy配列の値を乱数の条件に基づいて置き換える必要があります。numpy配列の値を乱数で置き換えます。

def add_noise(noise_factor=0.5): 

    chance = random.randint(1,100) 
    threshold_prob = noise_factor * 100. 

    if chance <= threshold_prob: 
     noise = float(np.random.randint(1,100)) 
    else: 
     noise = 0. 

    return(noise) 

しかし、私はnumpyの関数を呼び出すとき、それが発生した乱数と一致するすべての値を置き換えます:

np.place(X, X==0., add_noise(0.5)) 

私は、ランダムな値の時間の50%を追加する機能を持っています

この問題は、add_noise()が1回だけ実行され、すべての0の値がノイズ値で置き換えられることです。

私がしようとしているのは、numpy配列内のすべての要素を「反復」することです(条件== 0)、毎回add_noise()を使ってノイズ値を生成します。

これは、すべての行と列を通過するforループで行うことができますが、誰かがそれを行うより効率的な方法を知っていますか?

+0

投稿されたソリューションのいずれかがうまく機能しましたか? – Divakar

+0

はい、ベクトル化されたアプローチは良好でした。ありがとう。 –

答えて

1

は、ここに1つのベクトル化のアプローチだ -

noise_factor = 0.5 # Input param 

# Get mask of zero places and the count of it. Also compute threshold 
mask = X==0 
c = np.count_nonzero(mask) 
threshold_prob = noise_factor * 100. 

# Generate noise numbers for count number of times. 
# This is where vectorization comes into the play. 
nums = np.random.randint(1,100, c) 

# Finally piece of the vectorization comes through replacing that IF-ELSE 
# with np,where that does the same op of choosing but in a vectorized way 
vals = np.where(nums <= threshold_prob, np.random.randint(1,100, c) , 0) 

# Assign back into X 
X[mask] = vals 

追加の利点は、我々がadd_noise操作のため0smaskを再利用してもバックXに割り当てるためにしていることです。これは、np.placeの使用に代わるものであり、効率基準として意味されます。

さらなるパフォーマンスの向上

我々はnumsなどのように、第二工程において、その代わりに、一旦、再使用行うことによって乱数発生の2つの手順を使用valsを計算するステップでさらに最適化することができ -

nums = np.random.randint(1,100, (2,c)) 
vals = np.where(nums[0] <= threshold_prob, nums[1] , 0) 
0

関数をベクトル化すると、すべての要素に簡単に適用できます。また、私が想定しているとかなり効率的です。

import random 
import numpy as np 

def add_noise(x): 
    if not x: 
     if random.random() <= 0.5: 
      noise = float(np.random.randint(1,100)) 
      return noise 
     else: 
      return 0 
    else: 
     return x 

x = np.zeros(shape=(10, 10)) 

n = np.vectorize(add_noise) 
x = n(x) 
0

私が正しく理解している場合、numpy配列の値を2つの条件に基づいてランダム値に変更したいとします。

  1. 値は、2枚のマスクを作成し、np.logical_andとそれらを組み合わせることができ、これらの二つの条件のためにゼロ
  2. いくつかの偶然の要因

でなければなりません。また、np.randomメソッドを使用して乱数の配列を取得することもできます。

import numpy as np 

def add_perhaps_noise_if_zero(x, threshold=0.5): 
    mask_1 = x == 0.0 
    mask_2 = np.random.random(x.shape) <= threshold 
    mask_combined = np.logical_and(mask_1, mask_2) 
    x[mask_combined] += np.random.random(x.shape)[mask_combined] 
    return x 


x = np.zeros((5,5)) 
for i in range(5): 
    print(x) 
    x = add_perhaps_noise_if_zero(x) 
関連する問題