在Python中使用numpy/scipy进行binning的矢量化方法

5 python arrays numpy scipy

我正在使用np.digitize将Python中的2d数组(x by y)合并到其x值的区间(在"bins"中给出):

elements_to_bins = digitize(vals, bins)
Run Code Online (Sandbox Code Playgroud)

其中"vals"是一个二维数组,即:

 vals = array([[1, v1], [2, v2], ...]). 
Run Code Online (Sandbox Code Playgroud)

elements_to_bins只是说每个元素落入哪个bin.我当时想要做的是得到一个列表,其长度是"箱子"中的箱数,每个元素返回落入该箱的"val"的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)
Run Code Online (Sandbox Code Playgroud)

有没有更优雅/更简单的方法来做到这一点?我只需要列出每个bin中的y值列表.

谢谢.

Eri*_*got 3

如果我正确理解你的问题:

\n\n
vals = array([[1, 10], [1, 11], [2, 20], [2, 21], [2, 22]])  # Example\n\n(x, y) = vals.T  # Shortcut\nbin_limits = range(min(x)+1, max(x)+2)  # Other limits could be chosen\npoints_by_bin = [ []\xc2\xa0for _ in bin_limits ]  # Final result\nfor (bin_num, y_value) in zip(searchsorted(bin_limits, x, "right"), y):  # digitize() finds the correct bin number\n    points_by_bin[bin_num].append(y_value)\n\nprint points_by_bin  # [[10, 11], [20, 21, 22]]\n
Run Code Online (Sandbox Code Playgroud)\n\n

Numpy 的快速数组运算searchsorted()用于实现最大效率。然后将值一一相加(由于最终结果不是矩形数组,因此 Numpy 对此无能为力)。此解决方案应该比循环中的多次调用更快 ,循环中的多次调用迫使 Numpy多次where()重新读取同一数组。

\n

  • 由于性能原因,应优先选择 numpy.searchsorted 进行数字化:https://github.com/numpy/numpy/issues/2656 (2认同)