使用自定义谓词对 numpy 数组进行排序

Posted

技术标签:

【中文标题】使用自定义谓词对 numpy 数组进行排序【英文标题】:sort numpy array with custom predicate 【发布时间】:2018-01-29 15:50:16 【问题描述】:

我想使用对第二维向量 (size:4) 进行操作的自定义谓词,沿第一维 (size:n) 对形状为 [n,4] 的 numpy 数组进行排序。我想做的 C++ 版本如下,真的很简单。我已经看到如何使用python lists 执行此操作,但我找不到使用 numpy 数组执行此操作的语法。这可能吗?关于 np.sort、np.argsort、np.lexsort 的文档没有提到自定义谓词。

// c++ version
vector< float[4] > v = init_v(); 
float[4] p = init_p();
std::sort(v.begin(), v.end(), [&p](const auto& lhs, const auto& rhs) 
   return myfn(p, lhs) > myfn(p, rhs); );

编辑: 下面是我想用于排序的python代码。 IE。对于我的数组的每个“行”(n:4),我会计算欧几里得 3D 距离(即只有前 3 列)到一个固定点的平方。

# these both operate on numpy vectors of shape [4] (i.e. a single row of my data matrix)
def dist_sq(a,b):
    d = a[:3]-b[:3]
    return np.dot(d*d)

def sort_pred(lhs, rhs, p):
    return dist_sq(lhs, p) > dist_sq(rhs, p)

【问题讨论】:

【参考方案1】:

在 numpy 中,您可以将(矢量化)顺序定义函数应用于数组,然后使用 np.argsort 按结果排序。

这比 C++ 版本的空间效率低,但这是您通常使用 numpy 实现性能的方式。

import numpy as np    

def myfn(x):
    return np.sin(x[:, 1])  # example: sort by the sine of the second column

a = np.random.randn(10, 4)

predicate = myfn(a)  # not sure if predicate is the best name for this variable
order = np.argsort(predicate)

a_sorted = a[order]

【讨论】:

这是一个很好的方法,但它不能处理多个键的排序 --- iow,主要是 A 列,其次是 B 列,等等。 @KylePena 为此,您可以使用numpy.lexsort 而不是numpy.argsort。直接传递数组或应用此 Q/A 中的谓词转换。 这并不能解决问题。 @memo 只想在给定一个比较两个对象的函数的情况下订购一组对象。 Argsort 仅适用于以数字形式表示的对象。 @JoshAlbert 这在编辑之前回答了这个问题。而且,显然,答案仍然适用于 OP。如果您认为此答案不足,请随时发布替代答案。

以上是关于使用自定义谓词对 numpy 数组进行排序的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义顺序对数组进行排序

php多维数组自定义排序 uasort()

php多维数组自定义排序 uasort()

如何对实体的自定义属性进行谓词

按自定义数组对行进行排序

usort — 使用用户自定义的比较函数对数组中的值进行排序