【发布时间】:2017-09-22 20:53:55
【问题描述】:
问题描述
我有一个 3D numpy 数组,表示为 data,形状为 N x R x C,即 N 个样本,R 行和 C 列。我想为样本和行的每个组合获取沿列的直方图。然而,固定长度 S 的 bin 边缘(参见 numpy.histogram 中的参数 bins)在不同行将不同,但在样本之间共享。考虑这个例子来说明,对于第一个样本 (data[0]),其第一行的 bin 边缘序列与其第二行的 bin 边缘序列不同,但与第二个样本的第一行的 bin 边缘序列相同 (data[1] )。因此,所有 bin 边缘序列都存储在形状为 R x S 的 2D numpy 数组中,表示为bin_edges。
我的问题是如何有效地计算直方图?
一个有效但缓慢的解决方案
使用numpy.histogram,我能够想出一个可行但相当慢的解决方案,如下面的代码 sn-p 所示
```
Get dummy data
N: number of samples
R: number of rows (or kernels)
C: number of columns (or pixels)
S: number of bins
```
import numpy as np
N, R, C, S = 100, 50, 1000, 10
data = np.random.randn(N, R, C)
# for each row/kernel, pool pixels of all samples
poolsamples = np.swapaxes(data, 0, 1).reshape(R, -1)
# use quantiles as bin edges
percentiles = np.linspace(0, 100, num=(S + 1))
bin_edges = np.transpose(np.percentile(poolsamples, percentiles, axis=1))
```
A working but slow solution of getting histograms along column
```
hist = np.empty((N, R, S))
for idx in np.arange(R):
bin_edges_i = bin_edges[idx, :]
counts = np.apply_along_axis(
lambda a: np.histogram(a, bins=bin_edges_i)[0],
1, data[:, idx, :])
hist[:, idx, :] = counts
可能的方向
- 花式 numpy 重塑以避免使用 for 循环
- 此问题源于为通过训练的神经网络转发的每个图像提取低端特征。因此,如果直方图的提取可以嵌入到 TensorFlow 图中,最终在 GPU 上进行,那就再理想不过了!
- 我注意到一个 python 包fast-histogram 声称比
numpy.histogram快7-15 倍。然而,一维直方图函数只能采用 bin 数量而不是实际 bin 位置 - numexpr?
我很想听听任何意见!提前致谢!
【问题讨论】:
标签: performance numpy tensorflow gpu histogram