2012-03-30 5 views
0

Здравствуйте, я новый пользователь для Python, и у меня возникла проблема с тем, что я представлял, было довольно простой задачей.Совокупные ежедневные данные для расчета среднемесячного значения

У меня есть несколько (> 50) csv файлов, содержащих ежедневные данные глубины снега. Я хотел бы перебирать файлы csv и рассчитывать ежемесячные средства для глубины снега. Пример данных:

Date,SD 
1/1/2000,36 
1/2/2000,36 
1/3/2000,38 
1/4/2000,40 
2/1/2000,48 
2/2/2000,48 

Другими словами, я хотел бы рассчитать ежемесячные снега глубины средних и записать вывод в новый файл CSV. Мне удалось изменить другой пример кода для моих данных, но я получаю ключевые ошибки для использования Date в качестве ключевого значения в моем словаре.

Любые советы?

код до сих пор:

from __future__ import division 
import csv 
from collections import defaultdict 

def default_factory(): 
    return [0, None, None, 0] 

reader = csv.DictReader(open(r'C:\SandBox\VALIDATION\TestTable.csv')) 

dates = defaultdict(default_factory) 
for row in reader: 
    sd = int(row["SD"]) 
    dates[row["Dates"]][0] += sd 
    max = dates[row["Dates"]][1] 
    dates[row["Dates"]][1] = amount if max is None else amount if amount > max else max 
    min = dates[row["Date"]][2] 
    dates[row["Dates"]][2] = amount if min is None else amount if amount < min else min 
    dates[row["Dates"]][3] += 1 

for date in dates: 
    dates[date][3] = dates[date][0]/dates[date][3] 

writer = csv.writer(open(r'C:\SandBox\VALIDATION\TestAvg.csv', 'w', newline = '')) 
writer.writerow(["Date", "SD", "max", "min", "mean"]) 
writer.writerows([date] + dates[date] for date in dates) 

EDIT: Просто чтобы прояснить, я пытаюсь добиться полного среднемесячные, т.е. января означают, февраль значит, и т.д. ... не вычислить среднее значение для одной даты.

+2

Можете ли вы опубликовать весь стек/ошибку? – jgritty

+2

Если вы вычисляете среднее значение и не медианное, почему вы заботитесь о минимальном и максимальном? – jgritty

+1

Дата, Снег или Даты, SD? – WolframH

ответ

0

Вы можете использовать словарь, чтобы сделать код немного более читаемым.

from __future__ import division 
import csv 
from collections import defaultdict 

def default_factory(): 
    return { "sum": 0, "max": None, "min": None, "count": 0} 

reader = csv.DictReader(open(r'sd.csv')) 

dates = defaultdict(default_factory) 
rows = [] 
for row in reader: 
    date = row["Date"] 
    sd = int(row["Snowdepth"]) 
    rows.append([date, sd]) 
    month = date.split("/")[0] 
    r = dates[month] 
    r["sum"] += sd 
    max = r["max"] 
    r["max"] = sd if max is None else sd if sd > max else max 
    min = r["min"] 
    r["min"] = sd if min is None else sd if sd < min else min 
    r["count"] += 1 

for date in dates: 
    r = dates[date] 
    r["avg"] = r["sum"]/r["count"] 

writer = csv.writer(open(r'TestAvg.csv', 'w')) 
writer.writerow(["Date", "SD", "max", "min", "mean"]) 
for row in rows: 
    r = dates[row[0].split("/")[0]] 
    writer.writerow(row + [r["max"], r["min"], r["avg"]]) 
+0

Спасибо, Gebb, работал очень хорошо! –

0

Someplaces вы использовали Dates в качестве имени столбца (например, max = dates[row["Dates"]][1]), и другое место этого Date (например min = dates[row["Date"]][2]), от вас пример данные выглядят Date это имя столбца? поэтому, если вы используете одно и то же имя везде, это должно быть хорошо, например.

s="""Date,Snowdepth 
1/1/2000,36 
1/2/2000,36 
1/3/2000,38 
1/4/2000,40 
2/1/2000,48 
2/2/2000,48""" 

import StringIO 
import csv 
reader = csv.DictReader(StringIO.StringIO(s)) 

for row in reader: 
    print row['Date'] 

выход:

1/1/2000 
1/2/2000 
1/3/2000 
1/4/2000 
2/1/2000 
2/2/2000 
0
from __future__ import division 
import csv 
from collections import defaultdict 

def default_factory(): 
    return [0, None, None, 0] 

reader = csv.DictReader(open(r'snow_data.csv')) 

dates = defaultdict(default_factory) 

for row in reader: 
    amount = int(row["Snowdepth"]) 
    dates[row["Date"]][0] += amount 
    max = dates[row["Date"]][1] 
    dates[row["Date"]][1] = amount if max is None else amount if amount > max else max 
    min = dates[row["Date"]][2] 
    dates[row["Date"]][2] = amount if min is None else amoun if amount < min else min 
    dates[row["Date"]][3] += 1 


for date in dates: 
    dates[date][3] = dates[date][0]/dates[date][3] 

writer = csv.writer(open(r'TestAvg.csv', 'w')) 
writer.writerow(["Date", "Snowdepth", "max", "min", "mean"]) 
writer.writerows([date] + dates[date] for date in dates) 

Я установил код, чтобы использовать Date и Snowdepth везде, как, то есть то, что ваш образец CSV обеспечивает. Кроме того, у вас была переменная amount, которая должна была быть sd, иначе сумма не определена. Я сделал это один amount всюду.

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

Например, вот выход из вашего образца CSV:

Date,Snowdepth,max,min,mean 

1/3/2000,38,38,38,38.0 

2/2/2000,48,48,48,48.0 

2/1/2000,48,48,48,48.0 

1/4/2000,40,40,40,40.0 

1/1/2000,36,36,36,36.0 

1/2/2000,36,36,36,36.0 
+0

Я думаю, вы неправильно поняли мой вопрос. Я хотел бы достичь среднемесячного значения (т. Е. Среднее значение в январе 36,6667), а не среднесуточного. –

+0

О, хорошо, я полностью пропустил эту часть. – jgritty

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