【问题标题】:Numpy histogram on multi-dimensional array多维数组上的 Numpy 直方图
【发布时间】:2013-09-21 23:41:50
【问题描述】:

给定一个形状为(n_days, n_lat, n_lon) 的np.array,我想为每个经纬度单元计算一个带有固定箱的直方图(即每日值的分布)。

该问题的一个简单解决方案是遍历单元格并为每个单元格调用np.histogram::

bins = np.linspace(0, 1.0, 10)
B = np.rand(n_days, n_lat, n_lon)
H = np.zeros((n_bins, n_lat, n_lon), dtype=np.int32)
for lat in range(n_lat):
    for lon in range(n_lon):
        H[:, lat, lon] = np.histogram(A[:, lat, lon], bins=bins)[0]
# note: code not tested

但这很慢。有没有更高效的不涉及循环的解决方案?

我查看了 np.searchsorted 以获取 B 中每个值的 bin 索引,然后使用精美的索引更新 H::

bin_indices = bins.searchsorted(B)
H[bin_indices.ravel(), idx[0], idx[1]] += 1  # where idx is a index grid given by np.indices
# note: code not tested

但这不起作用,因为就地添加运算符 (+=) 似乎不支持同一单元格的多次更新。

谢谢, 彼得

【问题讨论】:

  • 似乎github.com/numpy/numpy/pull/2821 解决了花哨的索引和就地问题。 numpy 不允许多次更新的原因是 a[idx] += 1 与 a[idx] = a[idx] + 1 不同。
  • 使用 np.histogram2d 和 weights 关键字参数。
  • @Jaime 我将如何使用weights?我不想做二维直方图。
  • 还有一个np.histogramdd函数。

标签: python arrays numpy histogram


【解决方案1】:

也许这行得通?:

import numpy as np
n_days=31
n_lat=10
n_lon=10
n_bins=10
bins = np.linspace(0, 1.0, n_bins)
B = np.random.rand(n_days, n_lat, n_lon)


# flatten to 1D
C=np.reshape(B,n_days*n_lat*n_lon)
# use digitize to get the index of the bin to which the numbers belong
D=np.digitize(C,bins)-1
# reshape the results back to the original shape
result=np.reshape(D,(n_days, n_lat, n_lon))

【讨论】:

  • 这给了我与bins.searchsorted(B)基本相同的形状(n_days, n_lat, n_lon)的数组,但棘手的部分是如何将其转换为(n_bins, n_lat, n_lon)。
【解决方案2】:

您可以使用 numpy.apply_along_axis 来消除循环。

hist, bin_edges = apply_along_axis(lambda x: histogram(x, bins=bins), 0, B)

【讨论】:

  • @PeterPrettenhofer 刚刚修正了一个错字。 lambda 有字母转置。希望这对你有用。
猜你喜欢
  • 2021-01-17
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多