2

У меня есть большой файл, полный записей, подобных этой

1, 2, 4, 5, 6
1, 3, 5, 6, 3
1, 4, 5, 6, 6
2, 4, 5, 5, 5
2, 3, 4, 5, 2

в любом случае мне нужно взять среднее значение по всем строкам с одним и тем же первым номером (ключом). т.е.

1, 3, 4.66, 5.66, 5
2, 3.5, 4.5, 5, 3.5

Я знаю, что для этого отлично подойдет awk/sed, просто у меня недостаточно опыта, чтобы выполнить это, спасибо!

Кроме того, как насчет усреднения этих столбцов вместе? Итак, после того, как я вывел это в файл, id хотел бы получить еще один подобный:

1, 4.58
1, 4.125

Количество добавляемых столбцов также не всегда может быть равно 4.

РЕДАКТИРОВАТЬ: это может быть проще сделать в gnuplot, поэтому мне в основном нужен ответ на первую часть.

3 ответа3

2

Для первого варианта:

awk -F, 'BEGIN { OFS=","} {if (!keys[$1]) {keys[$1] = 1}; for (i=2;i<=NF;i++){array[$1,i]+=$i}; count[$1]+=1}END{for (i in keys) {printf ("%s ", i); for (j=2;j<=NF;j++) {printf ("%.2f ", array[i,j]/count[i])}; printf ("%s","\n")}}' inputfile

Для второго варианта:

awk -F, 'BEGIN { OFS=","} {if (!keys[$1]) {keys[$1] = 1}; for (i=2;i<=NF;i++){array[$1,i]+=$i}; count[$1]+=1}END{for (i in keys) {{printf ("%s ", i); sum = 0; for (j=2;j<=NF;j++) {sum += array[i,j]/count[i]}}; printf ("%.2f\n",sum/(NF-1))}}' inputfile

но я не уверен, что понимаю, почему вы хотите получить среднее значение для некоторых средних.

0

У Karthik есть хорошее предложение сделать это в Numpy: это всего лишь несколько строк,

import numpy
data = numpy.loadtxt('filename.txt')
for key in numpy.unique(data.T[0]):
    print data[data.T[0]==key].mean(0)

Или, если вы хотите усреднить столбцы вместе, последняя строка изменится на

    avgs = data[data.T[0]==key].mean(0)[1:]
    print avgs[0], avgs[1:].mean()
0

Это удивительно сложно и сложно с использованием Sed, поэтому вот что делает Python:

#!/usr/bin/env python

f = open("mycsv","r")
values = {}
index = {}
for line in f:
    rownum = line.strip().split(", ")
    try:
        values[rownum[0]] = map(lambda x,y: x+y, values[rownum[0]], [float(x) for x in rownum[1:]])
        index[rownum[0]] += 1
    except KeyError:
        values[rownum[0]] = [ float(x) for x in rownum[1:] ]
        index[rownum[0]] = 1

for k,v in values.items():
    values[k] = [x/index[k] for x in values[k]]
    print k, ":", values[k]

Это работает независимо от порядка строк, если строки с одинаковым первым элементом имеют одинаковую длину.

Усреднение столбцов вместе займет всего одну строчку Python в цикле for:

print reduce(lambda x,y: x+y, values[k])/len(values[k])

Тем не менее, учитывая колоссальное количество пониманий списков, вам, вероятно, лучше решить эту проблему с помощью NumPy или Matlab.

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