5

我有一个从低到高排序的数组,其中包含超过 260k 的值。我已经找到了数组的平均值(平均值)和中位数,只需要找出模式?

我不能使用 PHP 拥有的任何数学函数,它必须全部手动完成。

我想要它,所以可能只有一个值是模式,但可能有多个值可以是模式。我还需要能够记录值被存储的次数。例如数字 51 出现 6 次,所以我可以打印这两个值。

到目前为止,这是我的代码:

$amountRecords = 0;
$totalValue = 0;
$valueArray = array();

// reads in csv file
$handle = fopen('Task1-DataForMeanMedianMode.csv', 'r');
// to skip the header names/values
fgetcsv($handle);

// creates array containing variables of csv file in ascending order
while(($row = fgetcsv($handle, "\r")) != FALSE)
{

    // if amountRecords equals 0
    if($amountRecords == 0)
    {

        // adds value from csv to array
        $valueArray[] = $row[1];

    } // else amountRecords does not equal 0
    else 
    {

        // if the value in array location before is greater than the current value from the csv file
        if($valueArray[$amountRecords - 1] > $row[1])
        {

             // the current array location becomes the one in the location before
             $valueArray[] = $valueArray[$amountRecords - 1];
             // add the value from the csv to the location before
             $valueArray[$amountRecords - 1] = $row[1];

         } // if the value in the location before is not greater than the current value in the csv file
         else 
         {

             // adds value from csv to array
             $valueArray[] = $row[1];

         }

    }

    // calculates the total value of the values in csv file
    $totalValue = $totalValue + $row[1];
    // calculates the number of values in the csv file
    $amountRecords++;

}    

// calculate average value of payments
$averageValue = $totalValue / $amountRecords;
// limit integer to 2 decimal place
$average = number_format($averageValue,2,'.','');

// finds middle value
$middle = floor(($amountRecords / 2) - 1);

// calculates the median value
// if array size is even
if($amountRecords % 2 == 0)
{

    // calculates median
    $median = $valueArray[$middle];

} 
else // if array size is odd
{

    // calculate low and high values
    $low = $valueArray[$middle];
    $high = $valueArray[$middle + 1];
    // calculates median
    $median = (($low + $high) / 2);

}

// works out mode
// creates array count
$count = array();
// for each value in the valueArray
foreach( $valueArray as $value )
{

    if( isset( $count[$value] ))
    {

        $count[$value]++;

    }
    else
    {

        $count[$value] = 1;

    }

}

$mostCommon = "";
$iter = 0;

foreach( $count as $k => $v )
{

     if( $v > $iter )
     {

         $mostCommon = $k;
         $iter = $v;

     }

}

$modeArray = array( "mode" => $mostCommon , "count" => $iter );
4

5 回答 5

25

数字集的众数是出现频率最高的数字。您可以使用 PHP 使用类似于以下的代码执行此操作:

$values = array_count_values($valueArray); 
$mode = array_search(max($values), $values);
于 2012-08-20T10:39:06.353 回答
1

简单的!

$arr = array(4,6,7,1,4,7,4,7,1);
$freq = array();
for($i=0; $i<count($arr); $i++)
{
   if(isset($freq[$arr[$i]])==false)
   {
       $freq[$arr[$i]] = 1;
   }
   else
   {
       $freq[$arr[$i]]++;
   }
}
$maxs = array_keys($freq, max($freq));

for($i=0; $i<count($maxs); $i++)
{
   echo $maxs[$i] . ' ' . $freq[$maxs[$i]];
   echo '<br />';
}
于 2016-05-31T05:15:28.967 回答
0

仅数学解决方案:

    //sample data
$dataArr = ["1", "3", "5", "1", "3", "7", "1", "8", "1"];

//a multidimensional array to hold the keys (extracted fro above) and their values (number of occurrences)
$multiDArr = [];
for ($i = 0; $i < count($dataArr); $i++) {
    $key = $dataArr[$i];

    if (isset($multiDArr[$key])) {
        //key already exists; increment count of its value
        $multiDArr[$key] = $multiDArr[$key] + 1;
    } else {
        //key does nto exist; add it and an inital value of 1
        $multiDArr[$key] = 1;
    }
}

$highestOccuring = 0;
$highestOccuringKey = null;
foreach ($multiDArr as $key => $value) {

    if ($value > $highestOccuring) {
        $highestOccuring = $value;
        $highestOccuringKey = $key;
    }

}

echo "MODE / highest occuring key: " . $highestOccuringKey;
于 2019-12-11T10:14:03.133 回答
0
/** find array mode, most often see value
 * @param list(int) $a_in
 * @return list(int)
 */
function array_mode(array $a_in): array{
    $a_freq = [];
    foreach( $a_in as $v ) {
        if (!isset($a_freq[$v])) {
            $a_freq[$v] = 0;
        }
        $a_freq[$v]++;
    }
    $a_maxs = array_keys($a_freq, max($a_freq));
    return $a_maxs;
}
// test code
$a_in = [4,6,7,1,4,7,4,7,1];
array_mode( $a_in);
于 2021-07-30T12:09:00.287 回答
0

这将获取值并将其转换为模式数组。例如:print_r(get_mode(1,2,2,3,3,3,4,4,5,5,5,6,7,8,9));将返回,

Array
(
    [0] => Array
        (
            [value] => 3
            [count] => 3
        )

    [1] => Array
        (
            [value] => 5
            [count] => 3
        )

)

代码:

function get_mode(...$inputArray){
    $max=0;
    return array_reduce(
        array_values(array_reduce(array_values($inputArray),function($talliedArray,$inputNode){
            if(isset($talliedArray[(string)$inputNode])) 
                $talliedArray[(string)$inputNode]['count']++;
            else 
                $talliedArray[(string)$inputNode] = [
                    'value' => $inputNode,
                    'count' => 1
                ];
            return $talliedArray;
    },[])),function($modeArray,$talliedNode)use(&$max){
        if($talliedNode['count'] < $max) return $modeArray;
        if($talliedNode['count']=== $max) return array_merge($modeArray,[$talliedNode]);
        //if count > $max
        $max = $talliedNode['count'];
        return [$talliedNode];
    },[]);
}

这满足了“无数学函数”“多种返回模式”“有返回值和出现次数”

这只适用于字符串和数字。布尔值、对象和数组会变得很奇怪。

于 2021-08-30T19:52:12.590 回答