python - 对 numpy 数组进行排名以返回排名数组
问题描述
我有一个 3 维 NumPy 数组,表示 n 个维度为 x,x 的矩阵。例如,在 n=3 和 x=2 的情况下,示例如下:
matrices = np.array([[[2,8],[1,7]],[[3,1],[5,4]],[[9,6],[2,3]]]
matrices
array([[[2, 8],
[1, 7]],
[[3, 1],
[5, 4]],
[[9, 6],
[2, 3]]])
我想创建一个形状相同的新数组,但值是这些矩阵对每个元素的排名(即沿轴 0 排名)。结果如下:
array([[[1, 3],
[1, 3]],
[[2, 1],
[3, 2]],
[[3, 2],
[2, 1]]])
我可以看到如何排序 (np.argsort(matrices, axis=0)),但找不到返回排名的简单方法。矩阵尺寸 x 可能很高,因此快速运行时间很重要。此外,使用的 python 的分布不包括 scipy。
我发现以下工作:
def rank_stations(input):
output = [0] * (np.size(input))
for i, x in enumerate(sorted(range(len(input)), reverse=True, key=lambda y: input[y])):
output[x] = i+1
return output
results = np.apply_along_axis(rank_stations, 0, matrices)
使用尺寸为 980 x 980 的五个矩阵,运行时间约为 6 秒,而建模软件计算为 20 秒,因此这是一个合理的改进。排序算法在几分之一秒内运行,那么有没有办法通过排名获得相似的运行时间?
解决方案
numpy.apply_along_axis
与 一起使用scipy.stats.rankdata
:
from scipy.stats import rankdata
np.apply_along_axis(rankdata, 0, matrices)
或使用np.argsort
两次:
f = lambda x: x.argsort().argsort()
np.apply_along_axis(f, 0, matrices) + 1
输出:
array([[[1., 3.],
[1., 3.]],
[[2., 1.],
[3., 2.]],
[[3., 2.],
[2., 1.]]])
推荐阅读
- mysql - MySql 有 1.09 亿条记录 - 非常慢,有键
- node.js - 客户端调用调用外部 api 的服务器时出现 CORS 问题
- laravel - nginx fpm-php 基于位置的多个 laravel 实例
- ruby-on-rails - 将 2 个表中的记录组合成 1 个 ActiveRecord 模型
- c# - 如何在重用之前清理 ListViewItem 的状态?
- amazon-web-services - PMU x86-64 performance counters not showing in perf under AWS
- c# - 如何从 Rider 调试 WSL2 中的进程?
- javascript - 处理(P5JS)curveVertex 不连接第 1 和第 2 点,虽然 vertex() 会
- sql-server - 如何将多主 Microsoft SQL Server 数据库部署为 IaaS 或 AWS RDS
- questdb - 通过 SQL 插入记录时遇到错误代码 00000