当存在关系时,如何为数组分配排名

时间:2010-08-11 23:49:46

标签: php

当有关系时,我正在努力知道在尝试将数组中的排名分配给数组中时,从哪里开始。因此,例如,我需要像下面这样转换数组:

myarray = (4,76,34,13,34)

进入另一个数组,如:

myarray2 = (1,5,3.5,2,3.5)

基本上,当数组中同一个数字出现多次时,这些数字的分配等级是等级的平均值。因此,不是将两个34分别排在第3和第4,而是分配3.5。同样地,如果有34份副本,那么3份分配的等级将除以3.任何帮助都将非常感谢!

非常感谢,

亚当

4 个答案:

答案 0 :(得分:2)

这是一种方法。

<?php
$myarray       = array(4,76,34,13,34);

$sorted_array  = $myarray;
$grouped_array = array();
sort($sorted_array);
foreach ($sorted_array as $rank => $entry) {
    // Initialize the entry if it doesn't already exist
    if (empty($grouped_array[$entry])) {
        $grouped_array[$entry]['count'] = 1.0;
        $grouped_array[$entry]['total'] = $rank + 1; // Account for 0-based array
    } else {
        $grouped_array[$entry]['count'] += 1.0;
        $grouped_array[$entry]['total'] += $rank + 1; // Account for 0-based array
    }
}
$myarray2 = array();
foreach ($myarray as $entry) {
    // Get the average
    $myarray2[] = $grouped_array[$entry]['total'] / $grouped_array[$entry]['count'];
}

答案 1 :(得分:2)

我玩得很开心!

function rank($input) 
{
  $output = array();
  $ranking = $input; sort($ranking); $ranking = array_flip($ranking);
  $last_val = -1;
  foreach($ranking as $key => $val){
    $repetitions = ($val-$last_val-1);
    $last_val = $val;
    if($repetitions) {    
      $ranking[$key] = (($val*($repetitions+1))-($repetitions+1)*(($repetitions)/2))/($repetitions+1)+1 ;
    } else {
      $ranking[$key] = $val+1;
    }
  }
  foreach($input as $key => $val){
    $output[$key] = $ranking[$val];
  }
  return $output;
}

像这样使用:

$a = array(4,76,34,13,34);    
$c = rank($a);
print_r($c);

将输出:

Array
(
    [0] => 1
    [1] => 5
    [2] => 3.5
    [3] => 2
    [4] => 3.5
)

与:

相同
Array(1, 5, 3.5, 2, 3.5)

正如所料!

答案 2 :(得分:1)

我假设您还需要处理三个或四个或 n 值绑定在同一等级的情况。

我不是PHP大师,但这是定义排名函数的方法(伪代码):

define a = original array
define s = a.Sorted
define rank(n) = (s.FirstIndexOf(n) + s.LastIndexOf(n)) / 2

你可能需要在纸上做一些例子来说服自己,即使是三倍以上也是如此;它依赖s进行排序,以便重复是相邻的。

答案 3 :(得分:0)

接受的解决方案(以及其他解决方案)似乎比他们需要的更复杂:

function Rank($data) {
    $count = 0;
    $unique = $data; sort($unique);
    $unique = array_count_values($unique);

    foreach ($unique as $key => $frequency) {
        foreach (range(1, $frequency) as $i) {
            $unique[$key] += $count++;
        }

        $unique[$key] /= $frequency;
    }

    foreach ($data as $key => $value) {
        $data[$key] = $unique[$value];
    }

    return $data;
}

示例(demo):

print_r(Rank(array(4, 76, 34, 13, 34))); // 1; 5; 3.5; 2; 3.5
print_r(Rank(array(4, 76, 34, 13, 34, 34))); // 1; 6; 4; 2; 4; 4