使用 numpy percentile 为每一行获取不同的分位数
Get different quantile for each row using numpy percentile
我想使用 np.percentile
为每一行获取不同的分位数。
例如,给定这个 2 行数组,我想获得第一行的第 20 个百分位数和第二行的第 60 个百分位数。
dat = np.array([[1, 10, 3], [4, -1, 5]])
dat
# array([[ 1, 10, 3],
# [ 4, -1, 5]])
从第 20 个百分位数开始:
np.percentile(dat, 0.2, axis=1)
# array([ 1.008, -0.98 ])
第 60 个:
np.percentile(dat, 0.6, axis=1)
# array([ 1.024, -0.94 ])
基于此,理想的结果应该是[1.008, -0.94]
。
将向量作为分位数将结果扩展为 n
xn
数组:
np.percentile(dat, [0.2, 0.6], axis=1)
# array([[ 1.008, -0.98 ],
# [ 1.024, -0.94 ]])
这个结果的对角线产生正确的结果:
np.percentile(dat, [0.2, 0.6], axis=1).diagonal()
# array([ 1.008, -0.94 ])
但这对于较大的阵列来说成本过高。有没有办法直接计算每行对应分位数的百分位数?
将数组转换为 DataFrame
并将所需的分位数作为列后,您可以使用 apply
:
def percentile_qarray_df(dat, q):
# dat: numpy array.
# q: Vector with the same number of rows as dat.
df = pd.DataFrame(dat)
df['q'] = q
return df.apply(lambda x: np.percentile(x.drop('q'), x.q), axis=1)
例如:
percentile_qarray_df(dat, [0.2, 0.6])
# 0 1.008
# 1 -0.940
# dtype: float64
虽然这仍然很慢。
如果数据类型没有冲突,您可以连接百分位数和数据,然后使用 np.apply_along_axis
将百分位数与数据分开:
def percentile_qarray_np(dat, q):
return np.apply_along_axis(
lambda x: np.percentile(x[1:], x[0]),
1,
np.concatenate([np.array(q)[:, np.newaxis], dat], axis=1)
)
例如:
n = 10
percentiles = np.linspace(0, 100, n)
a = np.arange(n**2).reshape(n, n)
print(percentile_qarray_np(a, percentiles))
现在在 synthimpute
包中。
我想使用 np.percentile
为每一行获取不同的分位数。
例如,给定这个 2 行数组,我想获得第一行的第 20 个百分位数和第二行的第 60 个百分位数。
dat = np.array([[1, 10, 3], [4, -1, 5]])
dat
# array([[ 1, 10, 3],
# [ 4, -1, 5]])
从第 20 个百分位数开始:
np.percentile(dat, 0.2, axis=1)
# array([ 1.008, -0.98 ])
第 60 个:
np.percentile(dat, 0.6, axis=1)
# array([ 1.024, -0.94 ])
基于此,理想的结果应该是[1.008, -0.94]
。
将向量作为分位数将结果扩展为 n
xn
数组:
np.percentile(dat, [0.2, 0.6], axis=1)
# array([[ 1.008, -0.98 ],
# [ 1.024, -0.94 ]])
这个结果的对角线产生正确的结果:
np.percentile(dat, [0.2, 0.6], axis=1).diagonal()
# array([ 1.008, -0.94 ])
但这对于较大的阵列来说成本过高。有没有办法直接计算每行对应分位数的百分位数?
将数组转换为 DataFrame
并将所需的分位数作为列后,您可以使用 apply
:
def percentile_qarray_df(dat, q):
# dat: numpy array.
# q: Vector with the same number of rows as dat.
df = pd.DataFrame(dat)
df['q'] = q
return df.apply(lambda x: np.percentile(x.drop('q'), x.q), axis=1)
例如:
percentile_qarray_df(dat, [0.2, 0.6])
# 0 1.008
# 1 -0.940
# dtype: float64
虽然这仍然很慢。
如果数据类型没有冲突,您可以连接百分位数和数据,然后使用 np.apply_along_axis
将百分位数与数据分开:
def percentile_qarray_np(dat, q):
return np.apply_along_axis(
lambda x: np.percentile(x[1:], x[0]),
1,
np.concatenate([np.array(q)[:, np.newaxis], dat], axis=1)
)
例如:
n = 10
percentiles = np.linspace(0, 100, n)
a = np.arange(n**2).reshape(n, n)
print(percentile_qarray_np(a, percentiles))
现在在 synthimpute
包中。