3

Python でデータ処理を実行しようとしていますが、算術計算を行うネストされたループがあります。内側のループは 20.000 回実行されるため、次のコードは時間がかかります。

for foo in foo_list:
    # get bar_list for foo
    for bar in bar_list:
        # do calculations w/ foo & bar

このループは、Numpy または Scipy を使用して高速化できますか?

4

4 に答える 4

2

Numpyを使用する:

import numpy as np
foo = np.array(foo_list)[:,None]
bar = np.array(bar_list)[None,:]

それで

foo + bar

または他の操作によりlen(foo) * len(bar)、それぞれの結果を含む配列が作成されます。

例:

>>> foo_list = [10, 20, 30]
>>> bar_list = [4, 5]
>>> foo = np.array(foo_list)[:,None]
>>> bar = np.array(bar_list)[None,:]
>>> 2 * foo + bar

array([[24, 25],
       [44, 45],
       [64, 65]])
于 2012-10-11T14:14:57.240 に答える
0

私は画像処理にnumpyを使用しました。for(x in row){for y in column}を使用する前(またはその逆)、あなたはその考えを理解しました。

それは小さな画像には問題ありませんでしたが、RAMを喜んで消費します。代わりに、numpy.arrayに切り替えました。はるかに高速。

于 2012-10-11T14:16:16.913 に答える
0

これらが集計統計である場合は、Python Pandasの使用を検討してください。たとえば、すべての異なる(foo, bar)ペアに対して何かをしたい場合は、それらのアイテムをグループ化してから、ベクトル化された NumPy 操作を適用できます。

import pandas, numpy as np
df = pandas.DataFrame(
                      {'foo':[1,2,3,3,5,5], 
                       'bar':['a', 'b', 'b', 'b', 'c', 'c'], 
                       'colA':[1,2,3,4,5,6], 
                       'colB':[7,8,9,10,11,12]})
print df.to_string()

# Computed average of 'colA' weighted by values in 'colB', for each unique
# group of (foo, bar).
weighted_avgs  = df.groupby(['foo', 'bar']).apply(lambda x: (1.0*x['colA']*x['colB']).sum()/x['colB'].sum())

print weighted_avgs.to_string()

これにより、データ オブジェクトのみについて次のように出力されます。

  bar  colA  colB  foo
0   a     1     7    1
1   b     2     8    2
2   b     3     9    3
3   b     4    10    3
4   c     5    11    5
5   c     6    12    5

これはグループ化され、集計された出力です

foo  bar
1    a      1.000000
2    b      2.000000
3    b      3.526316
5    c      5.521739
于 2012-10-11T14:24:23.113 に答える
0

ループで実際に何が起こっているかに応じて、はい。
numpy では、配列と行列を使用できます。これにより、インデックスを作成してコードの実行を高速化し、場合によってはループをなくすことができます。

索引付けの例:

import magic_square as ms

a = ms.magic(5)

print a # a is an array
[[17 24  1  8 15]
 [23  5  7 14 16]
 [ 4  6 13 20 22]
 [10 12 19 21  3]
 [11 18 25  2  9]]

# Indexing example.  
b = a[a[:,1]>10]*10

print b
[[170, 240,  10,  80, 150],
 [100, 120, 190, 210,  30],
 [110, 180, 250,  20,  90]]

1 つまたは複数の配列を分析するときに、インデックスを作成することで速度が大幅に向上することは明らかです。強力なツールです...

于 2012-10-11T14:18:39.633 に答える