2012-04-12 6 views
1

날짜 그룹을 식별하고 그룹의 크기를 측정하는 함수를 쓰려고합니다.날짜 비교/연속 날짜 그룹화

이 함수는 날짜순으로 정렬 된 요소 목록 (요소는 날짜가있는 CSV 파일의 개별 행임)을 사용합니다. 리스트는 0 ~ n 엘리먼트 길이 일 수있다. 나는 입력 된대로 날짜 그룹의 크기를 추가하여리스트를 쓰고 싶다. 예

,

Bill 01/01/2011 3 

Bill 02/01/2011 3 

Bill 03/01/2011 3 

Bill 05/01/2011 1 

Bill 07/01/2011 1. 

는리스트 (이상적 파일로 인쇄)

Bill 01/01/2011 

Bill 02/01/2011 

Bill 03/01/2011 

Bill 05/01/2011 

Bill 07/01/2011 

되어야 출력 I 함수 이미 둘 사이의 델타를 반환 isBeside(string1, string2) 불렀다.

내 시도가 지금까지이

coll[i][1]은 CSV 라인의 날짜 요소를 포함 (반복적 인 혼란, 메신저 확실히 파이썬은 이보다 더 우아 할 수 있습니다)입니다.

def printSet(coll): 
    setSize = len(coll) 
    if setSize == 0: 
    #dont need to do anything 
elif setSize == 1: 

    for i in coll: 
     print i, 1 

elif setSize > 1: 

    printBuffer = [] ##new buffer list which will hold sequential dates, 
         until a non-sequential one is found 
    printBuffer.append(coll[0]) #add the first item 
    print 'Adding ' + str(coll[0]) 

    for i in range(0, len(coll)-1): 

     print 'Comparing ', coll[i][1], coll[i+1][1], isBeside(coll[i][1], coll[i+1][1]) 

     if isBeside(coll[i][1], coll[i+1][1]) == 1: 
      printBuffer.append(coll[i+1]) 
      print 'Adding ' + str(coll[i+1]) 
     else: 
      for j in printBuffer: 
       print j, len(printBuffer) 
      printBuffer = [] 
      printBuffer.append(coll[i]) 

return 
+0

이것은 데이터베이스가 매우 훌륭합니다. 대신 데이터베이스 사용을 고려 했습니까? – gfortune

+0

예. 내 문제는 CSV 파일에 많은 사람들과 다른 변수가 있다는 것입니다. 절차 적으로 나에게 앞으로 나아갈 길인 것처럼 보였다. 결국 주말이나 근무일을 확인해야 할 필요가 있습니다. 그렇기 때문에 DB가 작동하지 않을 것이라고 생각합니다. 그렇지 않으면 입증 될 것입니다. 나는이 메쏘드로 메신저가 닫히고 멀리 던지고 싶지 않다고 느낀다 : – Pythonn00b

+0

날짜는 월/일/년 형식인가, 또는 일/월/년인가? –

답변

1

이와 비슷한?

from datetime import date, timedelta 

coll = [['Bill', date(2011,1,1)], 
     ['Bill', date(2011,1,2)], 
     ['Bill', date(2011,1,3)], 
     ['Bill', date(2011,1,5)], 
     ['Bill', date(2011,1,7)]] 

res = [] 
group = [coll[0]] 
i = 1 

while i < len(coll): 
    row = coll[i] 
    last_in_group = group[-1] 

    # use your isBeside() function here... 
    if row[1] - last_in_group[1] == timedelta(days=1): 
     # consecutive, append to current group.. 
     group.append(row) 
    else: 
     # not consecutive, start new group. 
     res.append(group) 
     group = [row] 
    i += 1 

res.append(group) 

for group in res: 
    for row in group: 
     for item in row: 
      print item, 
     print len(group) 

그것은 인쇄 :

Bill 2011-01-01 3 
Bill 2011-01-02 3 
Bill 2011-01-03 3 
Bill 2011-01-05 1 
Bill 2011-01-07 1 
+0

이것은 완벽합니다. 그렇게 쉽게 읽을 수있게 해줘서 고마워. – Pythonn00b

0

datetime 모듈은 현재 사용중인 문자열 비교를하는 것보다 훨씬 청소기 될 것입니다 날짜, 작업을위한 매우 좋다. 실제로 day/month/year을하고 있다면 당신은 정상에 from datetime import timedelta를 추가로 datetime.strptime() 형식을 변경할 수

from datetime import datetime 

def add_month(dt): 
    # Normally you would use timedelta, but timedelta doesn't work with months 
    return dt.replace(year=dt.year + (dt.month==12), month=(dt.month%12) + 1) 

data = ['Bill 01/01/2011', 'Bill 02/01/2011', 'Bill 03/01/2011', 'Bill 05/01/2011', 'Bill 07/01/2011'] 
dates = [datetime.strptime(line.split(' ')[1], '%m/%d/%Y') for line in data] 
buffer = [data[0]] 
for i, date in enumerate(dates[1:]): 
    if add_month(dates[i]) == date: 
     buffer.append(data[i+1]) 
    else: 
     print '\n'.join(line + ' ' + str(len(buffer)) for line in buffer) 
     buffer = [data[i+1]] 

print '\n'.join(line + ' ' + str(len(buffer)) for line in buffer) 

나는 날짜가 양식 month/day/year에 있던 가정에 갔다 : 여기

은 예입니다 '%d/%m/%y'이고 add_month(dates[i]) == date 대신 date - dates[i] == timedelta(days=1)을 사용하십시오.