Python:如何找到点的二维分布的第 n 个分位数

Python: How to find the n-th quantile of a 2-d distribution of points

我有一个点的二维分布(粗略地说,两个 np.arraysxy),如附图所示。

如何 select 属于此类分布的第 n 个分位数的分布点?

我终于想出了一个解决方案,它看起来不是最优雅的,但效果相当不错: 要估计二维分布的分位数,可以使用 scipy 函数 binned_statistics,它允许将数据装箱 其中一个并在另一个中计算一些统计数据。 这是此类功能的文档: https://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.stats.binned_statistic.html 语法是: scipy.stats.binned_statistic(x, values, statistic='mean', bins=10, range=None)

首先,可以选择要使用的箱数,例如 Nbins=100。 接下来,可以定义一个用户函数作为输入 (这里有一个关于如何这样做的例子: ),我的例子是一个函数,它估计该 bin 中数据的 n-th 百分位数(我称之为 myperc)。最后定义了一个函数,例如它需要 xyNbinsnth(所需的百分位数)和 returns binned_statistics 给出3 个输出:statistic(该 bin 中所需统计信息的值),bin_edgesbinnumber(您的 data-point 在哪个 bin 中),还有 [= 的值18=] 在垃圾箱的中央 (bin_center)

def quantile2d(x,y,Nbins,nth):
    from numpy import percentile
    from scipy.stats import binned_statistic
    def myperc(x,n=nth):
        return(percentile(x,n))
    t=binned_statistic(x,y,statistic=myperc,bins=Nbins)
    v=[]
    for i in range(len(t[0])): v.append((t[1][i+1]+t[1][i])/2.)
    v=np.array(v)
    return(t,v)

因此 vt.statistic 将分别给出定义所需百分位数的曲线的 x 和 y 值。

Nbins=100
nth=30.
t,v=me.quantile2d(x,y,Nbins,nth)
ii=[]
for i in range(Nbins):
    ii=ii+np.argwhere(((t.binnumber==i) & (y<t.statistic[i]))).flatten().tolist()
ii=np.array(ii,dtype=int)

最后,这给出了以下情节:

plt.plot(x,y,'o',color='gray',ms=1,zorder=1)
plt.plot(v,t.statistic,'r-',zorder=3)
plt.plot(x[ii],y[ii],'o',color='blue',ms=1,zorder=2)

其中第30个百分位数的线显示为红色,该百分位数以下的数据显示为蓝色。