2011 年 9 月 30 日 + 32 日 = 2011 年 11 月 1 日なので、この例は機能しません。おそらく31日以内という意味でした。
Python で日付を扱う場合、datetime モジュールの datetime と timedelta を使用できます。strptime と strftime を使用して、'09/01/2011' のような文字列との間で変換します。
私は、最初にすべてを日時に変換し、すべての日付関連の処理を行い、必要に応じて最後に日付文字列に戻すことを好みます。
from datetime import datetime, timedelta
PERSON_ID = 0
START_DATE = 1
END_DATE = 2
def consolidate(records, maxgap=timedelta(days=31)):
consolidated = []
consolidated_start = records[0][START_DATE]
consolidated_end = records[0][END_DATE]
for person_id, start_date, end_date in records:
if start_date <= consolidated_end + maxgap:
consolidated_end = end_date
else:
consolidated.append([person_id, consolidated_start, consolidated_end])
consolidated_start = start_date
consolidated_end = end_date
else:
consolidated.append([person_id, consolidated_start, consolidated_end])
return consolidated
fmt = "%m/%d/%Y"
records = [[id, datetime.strptime(start, fmt), datetime.strptime(end, fmt)] for id, start, end in person_records]
records = consolidate(records)
records = [[id, start.strftime(fmt), end.strftime(fmt)] for id, start, end in records]
編集:ここではconsolidate()
、connected_components を使用するバージョンを示します。
import numpy as np
from scipy.sparse.csgraph import connected_components
def consolidate(records, maxgap=32):
person_id = records[0][0]
dates = np.array([[rec[1].date(), rec[2].date()] for rec in records], dtype='datetime64')
start_dates, end_dates = dates.T
gaps = start_dates[1:] - end_dates[:-1]
conns = np.diagflat(gaps < np.timedelta64(maxgap, 'D'), 1)
num_comps, comps = connected_components(conns)
return [[person_id,
min(start_dates[comps==i]).astype(datetime),
max(end_dates[comps==i]).astype(datetime)
] for i in range(num_comps)
]