Python 在给定分布时计算百分位数

Python 在给定分布时计算百分位数,python,numpy,Python,Numpy,假设我有一个值向量和一个概率向量。我想计算这些值的百分位数,但是使用给定的概率向量 比如说, import numpy as np vector = np.array([4, 2, 3, 1]) probs = np.array([0.7, 0.1, 0.1, 0.1]) 忽略probs,np。百分位(向量,10)给出1.3。但是,很明显,这里最低的10%的值为1,因此这将是我想要的输出 如果结果位于两个数据点之间,我更喜欢线性插值 我如何用Python最方便地解决这个问题?在我的示例中,ve

假设我有一个值向量和一个概率向量。我想计算这些值的百分位数,但是使用给定的概率向量

比如说,

import numpy as np
vector = np.array([4, 2, 3, 1])
probs = np.array([0.7, 0.1, 0.1, 0.1])
忽略
probs
np。百分位(向量,10)
给出
1.3
。但是,很明显,这里最低的10%的值为
1
,因此这将是我想要的输出

如果结果位于两个数据点之间,我更喜欢线性插值


我如何用Python最方便地解决这个问题?在我的示例中,
vector
将不会被排序<代码>问题的总和始终为
1
。根据合理的定义,我更喜欢不需要“非标准”软件包的解决方案。

一种解决方案是通过numpy.random.choice和numpy.percentile进行采样:

N = 50 # number of samples to draw
samples = np.random.choice(vector, size=N, p=probs, replace=True)
interpolation = "nearest"
print("25th percentile",np.percentile(samples, 25, interpolation=interpolation),)
print("75th percentile",np.percentile(samples, 75, interpolation=interpolation),)

根据数据类型(离散或连续),您可能希望为
插值
参数使用不同的值。

如果您准备对值进行排序,则可以构造插值函数,允许您计算概率分布的倒数。使用
scipy.interpolate
可能比使用纯
numpy
例程更容易做到这一点:

import scipy.interpolate
ordering = np.argsort(vector)
distribution = scipy.interpolate.interp1d(np.cumsum(probs[ordering]), vector[ordering], bounds_error=False, fill_value='extrapolate')
如果你用百分位数(在0..1范围内)询问这个分布,你应该得到你想要的答案,例如
分布(0.1)
给出1.0,
分布(0.5)
给出大约3.29


numpy的
interp()
函数也可以做类似的事情,避免了对scipy的额外依赖,但这需要在每次计算百分位数时重建插值函数。如果您在估计概率分布之前有一个已知的固定百分位数列表,那么这可能很好。

您希望的输出是什么?也许你可以补充一下。我在这里明确表示我想要的输出是
1
——这回答了你的问题吗?@FooBar哦,是的。我认为这是一个中间结果。