python numpy mask意味着性能

use*_*942 5 python arrays performance numpy masking

好吧,经过一番搜索,我似乎找不到直接解决这个问题的SO问题.我已经研究了蒙面阵列,虽然它们看起来很酷,但我不确定它们是否是我需要的.

考虑2个numpy数组:

zone_data是一个2维的numpy数组,具有相同值的元素块.这是我的"区域".

value_data 是一个2维numpy数组(zone_data的确切形状),具有任意值.

我寻找一个与zone_data/value_data相同形状的numpy数组,其中每个区域的平均值代替区号.

例子......在ascii艺术形式.

zone_data (4个不同的区域):

1, 1, 2, 2
1, 1, 2, 2
3, 3, 4, 4
3, 4, 4, 4
Run Code Online (Sandbox Code Playgroud)

value_data:

1, 2, 3, 6
3, 0, 2, 5
1, 1, 1, 0
2, 4, 2, 1
Run Code Online (Sandbox Code Playgroud)

我的结果,称之为result_data:

1.5, 1.5, 4.0, 4.0
1.5, 1.5, 4.0, 4.0
2.0, 2.0, 1.0, 1.0
2.0, 2.0, 1.0, 1.0
Run Code Online (Sandbox Code Playgroud)

这是我的代码.只要给我一个完美的结果,它工作得很好.

result_data = np.zeros(zone_data.shape)
for i in np.unique(zone_data):
    result_data[zone_data == i] = np.mean(value_data[zone_data == i])
Run Code Online (Sandbox Code Playgroud)

我的数组很大,我的代码片段需要几秒钟.我认为我有一个知识差距,没有任何有用的东西.循环方面需要委托给库或某些东西...... aarg!

我寻求帮助,使这个更快!蟒蛇神,我寻求你的智慧!

编辑 - 添加基准脚本

import numpy as np
import time

zones = np.random.randint(1000, size=(2000,1000))
values = np.random.rand(2000,1000)

print 'start method 1:'
start_time = time.time()

result_data = np.zeros(zones.shape)
for i in np.unique(zones):
    result_data[zones == i] = np.mean(values[zones == i])

print 'done method 1 in %.2f seconds' % (time.time() - start_time)

print
print 'start method 2:'
start_time = time.time()

#your method here!

print 'done method 2 in %.2f seconds' % (time.time() - start_time)
Run Code Online (Sandbox Code Playgroud)

我的输出:

start method 1:
done method 1 in 4.34 seconds

start method 2:
done method 2 in 0.00 seconds
Run Code Online (Sandbox Code Playgroud)

DSM*_*DSM 3

你可以使用np.bincount:

count = np.bincount(zones.flat)
tot = np.bincount(zones.flat, weights=values.flat)
avg = tot/count
result_data2 = avg[zones]
Run Code Online (Sandbox Code Playgroud)

这给了我

start method 1:
done method 1 in 3.13 seconds

start method 2:
done method 2 in 0.01 seconds
>>> 
>>> np.allclose(result_data, result_data2)
True
Run Code Online (Sandbox Code Playgroud)