Python中numpy/scipy分块的矢量化方法

2024-04-28 21:20:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我用Python将一个2d数组(x乘y)放入x值的容器中(在“bins”中给出),使用数字化公司名称:

elements_to_bins = digitize(vals, bins)

其中“VAL”是一个二维数组,即:

^{pr2}$

elements\u-to-u-bins只说明每个元素属于哪个bin。然后我要做的是得到一个列表,其长度为“bins”中的bin数,每个元素返回落入该bin中的“vals”的y维。我现在这样做:

points_by_bins = []
for curr_bin in range(min(elements_to_bins), max(elements_to_bins) + 1):
    curr_indx = where(elements_to_bins == curr_bin)[0]
    curr_bin_vals = vals[:, curr_indx]
    points_by_bins.append(curr_bin_vals)

有没有更优雅/更简单的方法?我只需要一个列在每个箱子里的y值的列表。在

谢谢。在


Tags: to元素列表bybin公司数组elements
3条回答

如果我没弄错你的问题:

vals = array([[1, 10], [1, 11], [2, 20], [2, 21], [2, 22]])  # Example

(x, y) = vals.T  # Shortcut
bin_limits = range(min(x)+1, max(x)+2)  # Other limits could be chosen
points_by_bin = [ [] for _ in bin_limits ]  # Final result
for (bin_num, y_value) in zip(searchsorted(bin_limits, x, "right"), y):  # digitize() finds the correct bin number
    points_by_bin[bin_num].append(y_value)

print points_by_bin  # [[10, 11], [20, 21, 22]]

Numpy的快速数组操作searchsorted()用于实现最大效率。然后一个接一个地添加值(因为最终结果不是一个矩形数组,Numpy对此帮助不大)。这个解决方案应该比一个循环中的多个where()调用更快,这会迫使Numpy多次重新读取相同的数组。在

这将返回一个类似于IDL HISTOGRAM的Reverse_index的数据结构:

ovec = np.argsort(vals)
ivec = np.searchsorted(vals, bin_limits, sorter=ovec)

那么属于bin#i的元素列表是

^{pr2}$

(我的快速计时测试表明,这比EOL的算法快5倍,因为它不需要创建不同大小的列表)

bin键是否只是整数,没有binning,就像你的例子中那样?那么你就可以这样做了,不需要纽比:

from collections import defaultdict
bins = defaultdict(list)  # or [ [] ...] as in EOL

vals = [[1, 10], [1, 11], [2, 20], [2, 21], [2, 22]]  # nparray.tolist()
for nbin, val in vals:
    bins[nbin].append(val)

print "bins:", bins
# defaultdict(<type 'list'>, {1: [10, 11], 2: [20, 21, 22]})

相关问题 更多 >