PHP - 我需要什么代码来模拟 Python 中的 numpy.argsort 数组排序功能?

问题描述 投票:0回答:1

我在 PHP 中有以下数组,其中包含三角形 3 条边的长度:

$edge_lengths = array(
  [0]=>
  float(420)
  [1]=>
  float(593.9696961967)
  [2]=>
  float(420)
);

我现在需要对此数组进行排序,以便按相反顺序(从高到低)对值进行排序。如果有任何值匹配,则必须进一步按键以相反顺序(从高到低)对数组进行排序,以获得以下结果:

$edge_sorted = array(
  [1]=>
  float(593.9696961967)
  [2]=>
  float(420)
  [0]=>
  float(420)
);

在 Python 中,我可以用一行代码来完成此操作,如下所示:

edge_sorted = np.argsort(edge_lengths)[::-1]

然后将返回:

[1 2 0]

请注意,这仅返回索引列表;我不需要这样的积分。

我在 PHP 中尝试做同样事情的等效代码是这样的:

asort($edge_lengths, SORT_NUMERIC); // sort values in ascending order
$edge_lengths = array_reverse($edge_lengths, true); // reverse array and preserve keys
$edge_sorted = array();
foreach ($edge_sorted as $key => $value) {
   $edge_sorted[] = $key;
}

此代码几乎有效,但在某些值相同的情况下,键仍然按从低到高排序,而不是从高到低排序。我考虑过尝试使用

usort
uksort
编写比较函数,但我不知道从哪里开始,希望得到一些帮助。

php numpy sorting
1个回答
0
投票

没有一个 PHP 函数可以同时按键和值排序,您需要将输入转换为对数组,排序,然后将其转换回键控数组。

// you cannot directly compare floats and exect a sane answer
function float_compare($a, $b, $margin) {
    return abs($a - $b) <= $margin;
}

function edgesort($edges, $margin=0.00000000001) {
    $e = [];
    foreach($edges as $k => $v) {
        $e[] = [$k, $v];
    }
    
    usort($e, function($b, $a)use($margin){
        if( ! float_compare($a[1], $b[1], $margin) ) {
            return $a[1] <=> $b[1];
        }
        return $a[0] <=> $b[0];
    });
    
    $r = [];
    foreach($e as $i) {
        $r[$i[0]] = $i[1];
    }
    return $r;
}

$edge_lengths = [420, 593.9696961967, 420];

var_dump(edgesort($edge_lengths));

输出:

array(3) {
  [1]=>
  float(593.9696961967)
  [2]=>
  int(420)
  [0]=>
  int(420)
}

也就是说,如果您首先将值存储为

[edge_id, edge_length]
对,则会更简单。

© www.soinside.com 2019 - 2024. All rights reserved.