2014-09-29 63 views
1

塊我有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年我會在-B柱上生產的物品在A柱的總和,1行1列:

1925 53 
1950 15 

到目前爲止,我只能想出如何在CSV數據轉換文件爲int:

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 2014-09-29 12:11:37

+0

@unutbu - 推測'csv.reader'會像這樣創建:'csv.reader(o,delimiter ='',skipinitialspace = True)'或類似的東西? (以迎合非標準和可變空間分隔符)。 – mhawke 2014-09-29 12:31:42

+0

@mhawke:是的;由於OP在調用csv.reader的方式上似乎沒有問題,因此我沒有更改該代碼以適應數據的呈現方式。 – unutbu 2014-09-29 13:32:46

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會明白這一點。 – 2014-09-29 11:57:46

+0

@BurhanKhalid感謝您指出。已添加內嵌評論... – kundan 2014-09-29 12:07:07

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年,但這個想法是一樣的。