2016-07-21 24 views
1

辞書を使用して配列のリストの値を置き換えることにパフォーマンス上の問題があります。配列の大きなリスト(パフォーマンス)の値を置換する

のは、これが私の辞書であるとしましょう:

# Create a sample dictionary 

keys = [1, 2, 3, 4] 
values = [5, 6, 7, 8] 
dictionary = dict(zip(keys, values)) 

そしてこれは配列の私のリストです:

# import numpy as np 

# List of arrays 
listvalues = [] 

arr1 = np.array([1, 3, 2]) 
arr2 = np.array([1, 1, 2, 4]) 
arr3 = np.array([4, 3, 2]) 

listvalues.append(arr1) 
listvalues.append(arr2) 
listvalues.append(arr3) 

listvalues 
>[array([1, 3, 2]), array([1, 1, 2, 4]), array([4, 3, 2])] 

私はその後、使用のND nummpy配列内のすべての値を交換するには、次の機能を使用します辞書:

# Replace function 

def replace(arr, rep_dict): 

    rep_keys, rep_vals = np.array(list(zip(*sorted(rep_dict.items())))) 
    idces = np.digitize(arr, rep_keys, right=True) 

    return rep_vals[idces] 

この関数は本当に高速ですが、arのリストを反復処理する必要があります

これは、何千もの配列を反復処理する必要があるため、プロセスのボトルネックです。 for-loopを使用せずに同じ結果を得るにはどうすればよいですか?結果は入力と同じ形式(値が置き換えられた配列のリスト)であることが重要です

多くのありがとうございます!!

+0

をクリアしてください。 listvaluesは可変長の配列の非常に長い配列です。これらの短い配列の長さには自然な上限がありますか? –

+0

基本的には、配列はかなり短いですが、これらの配列またはリストの長さに自然な上限はありません。ほとんどの配列はlen 20より長くはありませんが、これが役に立ちますように! – cf2

+0

あなたのボトルネックは 'replace'関数であり、ループではありません。ループ内で重要なことは何も起こっていないので、ループの置換または並列化のパフォーマンスを向上させる必要があります。 – sirfz

答えて

2

これは、numpy_indexedパッケージを使用して効率的にトリックを行います。 'listvalues'のすべての値が 'keys'に存在することが保証されていれば、さらに単純化できます。しかし、それは読者の運動としては残念です。

import numpy_indexed as npi 
arr = np.concatenate(listvalues) 
idx = npi.indices(keys, arr, missing='mask') 
remap = np.logical_not(idx.mask) 
arr[remap] = np.array(values)[idx[remap]] 
replaced = np.array_split(arr, np.cumsum([len(a) for a in listvalues][:-1])) 
+0

素晴らしい、ありがとう!これは数秒ですべての値を置き換えます:)。しかし、私は、私のデータセット全体で 'arr [remap] = ...'を実行する際に警告を受け取ります。_DeprecationWarning:割り当てがエラーを起こします。おそらくインデックス結果の形状が値配列shape_と一致しないからです。 ! – cf2

+0

申し訳ありません。その誤りを犯さなかったり、私はそれに精通していませんでした。私はすぐにその原因を突き止めることはありません。どのバージョンを使用していますか? –

+0

Python 2.7x。知らせてくれてありがとうございます。私は明日より多くのテストを行うでしょう – cf2

関連する問題