首先熟悉np.unravel_index 会有所帮助。它将“平面索引”(即 binnumber!)转换为坐标元组。您可以将平面索引视为arr.ravel() 的索引,将坐标元组视为arr 的索引。例如,如果在下图中,我们将数字 0、1、2、3、4、5 视为 bin 编号:
| 0 | 1 | 2 |
---+---+---+---|
0 | 0 | 1 | 2 |
1 | 3 | 4 | 5 |
+---+---+---|
然后np.unravel_index(4, (2,3))
In [65]: np.unravel_index(4, (2,3))
Out[65]: (1, 1)
等于 (1,1),因为形状为 (2,3) 的数组中的第 4 个 bin 编号具有坐标 (1,1)。
那好吧。接下来,我们需要知道scipy.stats.binned_statistic_dd在内部给给定的bin边缘添加了两条边缘来处理异常值:
bin_edges = [np.r_[-np.inf, edge, np.inf] for edge in bin_edges]
所以bin编号对应的边缘坐标由
给出
edge_index = np.unravel_index(binnumber, [len(edge)-1 for edge in bin_edges])
(我们使用len(edge)-1是因为数组轴的形状比
边数。)
例如:
import itertools as IT
import numpy as np
import scipy.stats as stats
sample = np.array(list(IT.product(np.arange(5)-0.5,
np.arange(5)*10-5,
np.arange(5)*100-50)))
bins = [np.arange(4),
np.arange(4)*10,
np.arange(4)*100]
statistic, bin_edges, binnumber = stats.binned_statistic_dd(
sample=sample, values=sample, statistic='count',
bins=bins,
range=[(0,100)]*3)
bin_edges = [np.r_[-np.inf, edge, np.inf] for edge in bin_edges]
edge_index = np.unravel_index(binnumber, [len(edge)-1 for edge in bin_edges])
for samp, idx in zip(sample, zip(*edge_index)):
vert = [edge[i] for i, edge in zip(idx, bin_edges)]
print('{} goes in bin with left-most corner: {}'.format(samp, vert))
产量
[ -0.5 -5. -50. ] goes in bin with left-most corner: [-inf, -inf, -inf]
[ -0.5 -5. 50. ] goes in bin with left-most corner: [-inf, -inf, 0.0]
[ -0.5 -5. 150. ] goes in bin with left-most corner: [-inf, -inf, 100.0]
[ -0.5 -5. 250. ] goes in bin with left-most corner: [-inf, -inf, 200.0]
...