2014-09-29 4 views
1

У меня есть CSV-файл с 2 колонками, представляющий собой распределение элементов в год, который выглядит следующим образом:Группа строк в CSV по блокам 25

A  B 

1900 10 
1901 2 
1903 5 
1908 8 
1910 25 
1925 3 
1926 4 
1928 1 
1950 10 

и т.д., около 15000 строк.

При создании диаграммы распределения, основанной на этих данных, слишком много точек на топоре, не очень красивое. Я хочу группировать строки по блокам по 25 лет, так что в конце у меня было бы меньше очков на топор. Так, например, от 1900 до 1925 я бы сумму произведенных деталей, 1 строка в колонке и 1 строке в столбце B:

1925 53 
1950 15 

До сих пор я только фигурировал, как преобразовать данные в CSV файл в целое:

o=open('/dates_dist.csv', 'rU') 
mydata = csv.reader(o) 


def int_wrapper(mydata): 
    for v in reader: 
     yield map(int, v) 

reader = int_wrapper(mydata) 

не можете найти, как это сделать далее ...

ответ

3

Вы можете использовать itertools.groupby:

import itertools as IT 
import csv 

def int_wrapper(mydata): 
    for v in mydata: 
     yield map(int, v) 


with open('data', 'rU') as o: 
    mydata = csv.reader(o) 
    header = next(mydata) 
    reader = int_wrapper(mydata) 
    for key, group in IT.groupby(reader, lambda row: (row[0]-1)//25+1): 
     year = key*25 
     total = sum(row[1] for row in group) 
     print(year, total) 

дает

(1900, 10) 
(1925, 43) 
(1950, 15) 

Обратите внимание, что 1900 до 1925 (включительно) охватывает 26 лет, а не 25. Так если вы хотите группы 25 лет, учитывая то, как вы сообщаете итоги, вы, вероятно, хотите половину -оконный интервал (1900, 1925].


Выражение row[0]//25 занимает год и число делится на 25. это число будет одинаковым для всех чисел в диапазоне [1900, 1925). Чтобы сделать диапазон полуоткрытым слева, вычтите и добавьте 1: (row[0]-1)//25+1.

+0

Вау, это было быстро и идеально! Большое спасибо :) – user3241376

+0

@unutbu - Предположительно, 'csv.reader' будет создан следующим образом:' csv.reader (o, delimiter = '', skipinitialspace = True) 'или аналогичный? (для обслуживания нестандартного и переменного разделителя пробелов). – mhawke

+0

@mhawke: Да; поскольку у ОП не возникало проблемы с вызовом вызова 'csv.reader', я не изменял этот код, чтобы он соответствовал тому, как были представлены данные. – unutbu

0

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

if __name__ == '__main__': 

    o=open('dates_dist.csv', 'rU') 
    lines = o.read().split("\n") # Create a list having each line of the file 

    out_dict = {} 
    curr_date = 0; 
    curr_count = 0 
    chunk_sz = 25; #years 
    if len(lines) > 0: 
     line_split = lines[0].split(",") 
     start_year = int(line_split[0]) 
     curr_count = 0 

     # Iterate over each line of the file 
     for line in lines: 
      # Split at comma to get the year and the count. 
      # line_split[0] will be the year and line_split[1] will be the count. 
      line_split = line.split(",") 
      curr_year = int(line_split[0]) 
      time_delta = curr_year-start_year 

      if time_delta<chunk_sz or time_delta == chunk_sz: 
       curr_count = curr_count + int(line_split[1]) 
      else: 
       out_dict[start_year+chunk_sz] = curr_count 
       start_year = start_year+chunk_sz 
       curr_count = int(line_split[1]) 

      #print curr_year , curr_count  

     out_dict[start_year+chunk_sz] = curr_count 
    print out_dict   
+0

Вы могли бы добавить объяснение этому - я уверен, что OP это оценит. –

+0

@BurhanKhalid Спасибо, что указали это. Добавили встроенные комментарии ... – kundan

0

Вы можете создать фиктивный столбец и группу по ней после того, как делают некоторые целочисленное деление:

df['temp'] = df['A'] // 25 
>>> df 
     A B temp 
0 1900 10 76 
1 1901 2 76 
2 1903 5 76 
3 1908 8 76 
4 1910 25 76 
5 1925 3 77 
6 1926 4 77 
7 1928 1 77 
8 1950 10 78 

>>> df.groupby('temp').sum() 
     A B 
temp   
76 9522 50 
77 5779 8 
78 1950 10 

Мои номера немного отличаются от ваших, так как я технически группируя от 1900-1924, 1925-1949 , и 1950-1974 гг., но идея такая же.

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