1

次のようなレコード (person_id、start_date、end_date) のリストがあります。

person_records = [['1', '08/01/2011', '08/31/2011'],
                 ['1', '09/01/2011', '09/30/2011'],
                 ['1', '11/01/2011', '11/30/2011'],
                 ['1', '12/01/2011', '12/31/2011'],
                 ['1', '01/01/2012', '01/31/2012'],
                 ['1', '03/01/2012', '03/31/2012']]

各個人のレコードは、start_date の昇順で並べ替えられます。日付に基づいてレコードを結合し、最初の期間の start_date を開始日として記録し、最後の期間の end_date を終了日として記録することにより、期間が統合されます。ただし、ある期間の終わりから次の期間の開始までの時間が 32 日以内の場合は、これを連続した期間として扱う必要があります。それ以外の場合、これを 2 つの期間として扱います。

consolidated_person_records = [['1', '08/01/2011', '09/30/2011'],
                               ['1', '11/01/2011', '03/31/2012']]

Python 接続コンポーネントを使用してこれを行う方法はありますか?

4

2 に答える 2

0

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)
           ]
于 2016-02-04T06:22:17.563 に答える