У меня есть огромный файл (50 тыс. Строк) в следующем формате:

52370581 2116
17996781 4314
47818829 2584
61421045 2158
...
25145813 2274

Первое значение может присутствовать несколько раз, и я хочу вычислить среднее значение 2-го значения для каждого 1-го значения, используя терминал. В идеале я бы хотел получить медиану, мин и макс. Я могу легко понять все значения с помощью awk но мне было интересно, как это сделать для каждого значения.

2 ответа2

3
awk '{c[$1]++;s[$1]+=$2}END{for(i in c)print i,(s[i]/c[i])}' test.in

Более читабельно:

awk '
{ # Every line
    # Increment the key, add value to its sum
    count[$1]++
    sum[$1] += $2
}
END {
    # Go through all the numbers we saw
    for(number in count) {
        # Print the number followed by the average (sum/count) of its values
        print number, (sum[number]/count[number])
    }
}
' test.in

Обратите внимание, что числа будут выводиться в более или менее случайном порядке (некоторые хэш ключей). Получение min и max не так уж и плохо, просто добавьте их после count и sum в первом блоке. Медиана требует отслеживания каждого номера. Вы можете сделать это с помощью двумерного массива (или его эмуляции в awk), но я оставлю это в качестве упражнения для читателя.

0

Для среднего

awk '{if(NR==1){i=$1;}} {if($1~i){j+=$2;k++}} END{print "Average is " (j/k)}' <filename>

это предоставит вас в случае, если вы хотите сделать это только для значения в первой строке. Вместо NR==0 , если вы передаете переменную, вы можете сделать это для любого конкретного случая строки. Теперь, если вы хотите сделать это для каждой строки, то ниже awk сделает это за один проход

awk '{value[$1]+=$2;count[$1]++} END{for(indx in value)print "Avarage of " indx " is " (value[indx]/count[indx])}' <filename>

У awk есть двумерный массив, но я не знаком с этим, поэтому использую 2 массива, чтобы сохранить сумму элементов и считать. Любая другая операция, нам нужно изменить скрипт на основе операции

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .