2016-01-22 3 views
1

В качестве ввода у меня есть CSV-файл со временем и кучей чисел за каждый раз.Как группа по сумме и среднему столбцу в python?

Time,F1,F2,F3 
8:11,5,2,4 
9:25,9,8,2 
9:39,7,3,2 
9:53,6,5,1 
10:07,4,6,7 
10:21,7,3,1 
10:35,5,6,7 
11:49,1,2,1 
12:03,3,3,1 

Я хотел бы, чтобы выводить таблицу для каждого часа, сгруппированных по столбцу Avg и Сумма:

Time,SUM F1,SUM F2,SUM F3,AVG F1,AVG F2,AVG F3 
8:00,5,2,4,5,2,4 
9:00,22,16,5,7.3,5.3,1.6 
10:00,16,15,15,5.3,5,5 
11:00,1,2,1,1,2,1 
12:00,3,3,1,3,3,1 

До сих пор я смотрел на это делать со словарем, где час является ключ и значение представляет собой список счетчиков и сумм, а затем деление суммы на подсчет, чтобы получить среднее значение. Я уверен, что должен быть более чистый способ сделать это. Возможно, некоторые библиотеки могут работать с этим. Какие-либо предложения?

+0

Ваш подход прекрасен. Это не так много кода. Цикл, чтобы добавить вещи в три словаря, каждый из которых использует setdefault (час, []). Append (F1) и setdefault (час, []). Append (F2) и setdefault (час, []). Append (F3). Затем для каждого бита вы повторяете каждый час и вызываете «sum» над списком и делите по счету (список), заботясь о том, что происходит, когда ваш список пуст. –

+1

'Pandas' - хорошая библиотека для обработки данных такого рода: http://pandas.pydata.org/ – CoMartel

ответ

2

A pandas решение:

import pandas as pd 

df = pd.read_csv('f123.csv') 
df['Time'] = df['Time'].apply(lambda x: x.split(':')[0] + ':00') 
by_hour = df.groupby('Time') 
data = {} 
for name in ['F1', 'F2', 'F3']: 
    data['SUM ' + name] = by_hour[name].sum() 
    data['AVG ' + name] = by_hour[name].mean() 
res = pd.DataFrame(data) 
print(res) 

печатает:

  AVG F1 AVG F2 AVG F3 SUM F1 SUM F2 SUM F3 
Time              
10:00 5.333333 5.000000 5.000000  16  15  15 
11:00 1.000000 2.000000 1.000000  1  2  1 
12:00 3.000000 3.000000 1.000000  3  3  1 
8:00 5.000000 2.000000 4.000000  5  2  4 
9:00 7.333333 5.333333 1.666667  22  16  5 

Сохранить как CSV файл:

res.to_csv('res.csv') 

Это содержание от res.csv:

Time,AVG F1,AVG F2,AVG F3,SUM F1,SUM F2,SUM F3 
10:00,5.333333333333333,5.0,5.0,16,15,15 
11:00,1.0,2.0,1.0,1,2,1 
12:00,3.0,3.0,1.0,3,3,1 
8:00,5.0,2.0,4.0,5,2,4 
9:00,7.333333333333333,5.333333333333333,1.6666666666666667,22,16,5 
+0

Отличное решение! Как бы вы справлялись с новыми днями, учитывая столбцы с датами рядом с временем в формате «22 -01-16»? – user52028778

+0

Отлично, что это помогло. Панда очень хорошо читает и работает с датами в целом. Однако ответ на новый вопрос в комментарии действительно громоздкий. Было бы проще задать новый вопрос и связать его в комментарии отсюда. Я посмотрю на это. –

+0

Pands отлично смотрится, но манипулирование данными на первый взгляд не очень интуитивно, может быть, я должен посетить один из классов python-academy. Здесь я добавил новый вопрос: http://stackoverflow.com/questions/34944183/how-to-groupby-two-fields-in-pandas – user52028778

0

Ниже вы должны получить работу, он использует csv модуля Python для обработки файлов и itertools.groupby группировать записи по часу:

import csv 
from itertools import groupby, chain 

with open('input.csv', 'rb') as f_input, open('output.csv', 'wb') as f_output: 
    csv_input = csv.reader(f_input) 
    csv_output = csv.writer(f_output) 
    header = next(csv_input) 
    csv_output.writerow(["Time","SUM F1","SUM F2","SUM F3","AVG F1","AVG F2","AVG F3"]) 

    for k, g in groupby(csv_input, lambda x: int(x[0].split(':')[0])): 
     entries = [(int(f1), int(f2), int(f3)) for t, f1, f2, f3 in g] 
     sums = [(sum(x), sum(x)/float(len(entries))) for x in zip(*entries)] 
     row = ['{}:00'.format(k)] + list(chain.from_iterable(zip(*sums))) 
     csv_output.writerow(row) 

Это даст вам выходной файл CSV глядя, как это:

Time,SUM F1,SUM F2,SUM F3,AVG F1,AVG F2,AVG F3 
8:00,5,2,4,5.0,2.0,4.0 
9:00,22,16,5,7.333333333333333,5.333333333333333,1.6666666666666667 
10:00,16,15,15,5.333333333333333,5.0,5.0 
11:00,1,2,1,1.0,2.0,1.0 
12:00,3,3,1,3.0,3.0,1.0 

zip Используется для транспонирования записей столбцов.

Испытано с помощью Python 2.7.9

Смежные вопросы