如何找到 scipy.stats.binned_statistic_dd() 返回的给定 bin 编号的 bin 边缘?
How to find bin edges of given bin number returned by scipy.stats.binned_statistic_dd()?
我有一个 Nx3 阵列 mm。函数调用
c,edg,idx = scipy.stats.binned_statistic_dd(mm,[], statistic='count',bins=(30,20,10),rg=((3,5),(2,8),(4,6)))
returns idx,这是一个一维整数数组,表示 mm 的每个元素所在的 bin ,并且 edg 是包含 bin edges
的 3 个数组的列表
我需要的是根据 idx 中的 binnumber 找到给定 bin 的 bin 边缘。例如,给定 idx=[24,153,...,72] 我想找到 bin 153 的边缘,即该 bin 落在 edg。当然我可以通过 mm[153] 找到 bin 153 中的元素,但不能找到边缘。
为了清楚起见,我发布了这个 Nx3 案例。实际上,我正在寻找 NxD 案例的解决方案。
首先熟悉 np.unravel_index 会有所帮助。它将 "flat 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]
...
我有一个 Nx3 阵列 mm。函数调用
c,edg,idx = scipy.stats.binned_statistic_dd(mm,[], statistic='count',bins=(30,20,10),rg=((3,5),(2,8),(4,6)))
returns idx,这是一个一维整数数组,表示 mm 的每个元素所在的 bin ,并且 edg 是包含 bin edges
的 3 个数组的列表我需要的是根据 idx 中的 binnumber 找到给定 bin 的 bin 边缘。例如,给定 idx=[24,153,...,72] 我想找到 bin 153 的边缘,即该 bin 落在 edg。当然我可以通过 mm[153] 找到 bin 153 中的元素,但不能找到边缘。
为了清楚起见,我发布了这个 Nx3 案例。实际上,我正在寻找 NxD 案例的解决方案。
首先熟悉 np.unravel_index 会有所帮助。它将 "flat 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]
...