我试图找到由readline
函数生成的bin范围内的值的中位数。我将如何只选择bin范围内的值并对这些特定值进行运算?以下是我的数据和我要执行的操作的示例:
np.histrogram
y值可以具有任何与之关联的x值,例如:
x = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
所以,我试图在生成的第一个bin中找到129个值的中值y值,等等。
答案 0 :(得分:2)
一种方法是使用pandas.cut()
:
>>> import pandas as pd
>>> import numpy as np
>>> np.random.seed(444)
>>> x = np.random.randint(0, 25, size=100)
>>> _, bins = np.histogram(x)
>>> pd.Series(x).groupby(pd.cut(x, bins)).median()
(0.0, 2.4] 2.0
(2.4, 4.8] 3.0
(4.8, 7.2] 6.0
(7.2, 9.6] 8.5
(9.6, 12.0] 10.5
(12.0, 14.4] 13.0
(14.4, 16.8] 15.5
(16.8, 19.2] 18.0
(19.2, 21.6] 20.5
(21.6, 24.0] 23.0
dtype: float64
如果您想呆在NumPy,您可能想签出np.digitize()
。
答案 1 :(得分:0)
您可以通过使用计数作为索引对数据的排序版本进行切片来实现此目的:
x = np.random.rand(1000)
hist,bins = np.histogram(x)
ix = [0] + hist.cumsum().tolist()
# if don't mind sorting your original data, use x.sort() instead
xsorted = np.sort(x)
ix = [0] + hist.cumsum()
[np.median(x[i:j]) for i,j in zip(ix[:-1], ix[1:])]
它将中位数作为标准的Python列表。
答案 2 :(得分:0)
np.digitize
和np.searchsorted
将使您的数据与垃圾箱匹配。在这种情况下,后者是可取的,因为它进行的不必要检查更少(可以安全地假定您的垃圾箱已被分类)。
如果您查看np.histogram
的文档(“注释”部分),您会注意到垃圾箱在右侧全部都是半开的(最后一个除外)。这意味着您可以执行以下操作:
x = np.abs(np.random.normal(loc=0.75, scale=0.75, size=10000))
h, b = np.histogram(x)
ind = np.searchsorted(b, x, side='right')
现在ind
为每个数字包含一个标签,指示其属于哪个bin。您可以计算中位数:
m = [np.median(x[ind == label]) for label in range(b.size - 1)]
如果您能够对输入数据进行排序,则您的工作将变得更加轻松,因为您可以使用视图,而不是使用遮罩为每个分类提取数据。在这种情况下,np.split
是一个不错的选择:
x.sort()
sections = np.split(x, np.cumsum(h[:-1]))
m = [np.median(arr) for arr in sections]