我在Python中有一組記錄,包含一個id,至少一個屬性和一組日期範圍。我希望獲取每個ID的代碼,並將所有屬性匹配的記錄組合在一起,並且在日期範圍內沒有空白。在熊貓數據框中組合日期範圍
由於日期範圍沒有空隙,我的意思是一個記錄的結束日期大於或等於該id的下一個記錄。
例如,具有ID「10」,開始日期「2016-01-01」和結束日期「2017-01-01」的記錄可以與具有該ID的另一記錄合併,開始日期「2017 -01-01「,結束日期爲」2018-01-01「,但不能與」2017-01-10「開始的記錄合併,因爲與2017-01-01之間存在差距-01至2017-01-09。
下面是一些例子 -
有:
FruitID,FruitType,StartDate,EndDate
1,Apple,2015-01-01,2016-01-01
1,Apple,2016-01-01,2017-01-01
1,Apple,2017-01-01,2018-01-01
2,Orange,2015-01-01,2016-01-01
2,Orange,2016-05-31,2017-01-01
2,Orange,2017-01-01,2018-01-01
3,Banana,2015-01-01,2016-01-01
3,Banana,2016-01-01,2017-01-01
3,Blueberry,2017-01-01,2018-01-01
4,Mango,2015-01-01,2016-01-01
4,Kiwi,2016-09-15,2017-01-01
4,Mango,2017-01-01,2018-01-01
旺旺:
FruitID,FruitType,NewStartDate,NewEndDate
1,Apple,2015-01-01,2018-01-01
2,Orange,2015-01-01,2016-01-01
2,Orange,2016-05-31,2018-01-01
3,Banana,2015-01-01,2017-01-01
3,Blueberry,2017-01-01,2018-01-01
4,Mango,2015-01-01,2016-01-01
4,Kiwi,2016-09-15,2017-01-01
4,Mango,2017-01-01,2018-01-01
我目前的解決方案如下。它提供了我正在尋找的結果,但對於大型數據集,性能似乎並不好。此外,我的印象是,您通常希望避免在可能的情況下迭代數據幀的各個行。非常感謝您提供的任何幫助!
import pandas as pd
from dateutil.parser import parse
have = pd.DataFrame.from_items([('FruitID', [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]),
('FruitType', ['Apple', 'Apple', 'Apple', 'Orange', 'Orange', 'Orange', 'Banana', 'Banana', 'Blueberry', 'Mango', 'Kiwi', 'Mango']),
('StartDate', [parse(x) for x in ['2015-01-01', '2016-01-01', '2017-01-01', '2015-01-01', '2016-05-31',
'2017-01-01', '2015-01-01', '2016-01-01', '2017-01-01', '2015-01-01', '2016-09-15', '2017-01-01']]),
('EndDate', [parse(x) for x in ['2016-01-01', '2017-01-01', '2018-01-01', '2016-01-01', '2017-01-01',
'2018-01-01', '2016-01-01', '2017-01-01', '2018-01-01', '2016-01-01', '2017-01-01', '2018-01-01']])
])
have.sort_values(['FruitID', 'StartDate'])
rowlist = []
fruit_cur_row = None
for row in have.itertuples():
if fruit_cur_row is None:
fruit_cur_row = row._asdict()
fruit_cur_row.update(NewStartDate=row.StartDate, NewEndDate=row.EndDate)
elif not(fruit_cur_row.get('FruitType') == row.FruitType):
rowlist.append(fruit_cur_row)
fruit_cur_row = row._asdict()
fruit_cur_row.update(NewStartDate=row.StartDate, NewEndDate=row.EndDate)
elif (row.StartDate <= fruit_cur_row.get('NewEndDate')):
fruit_cur_row['NewEndDate'] = max(fruit_cur_row['NewEndDate'], row.EndDate)
else:
rowlist.append(fruit_cur_row)
fruit_cur_row = row._asdict()
fruit_cur_row.update(NewStartDate=row.StartDate, NewEndDate=row.EndDate)
rowlist.append(fruit_cur_row)
have_mrg = pd.DataFrame.from_dict(rowlist)
print(have_mrg[['FruitID', 'FruitType', 'NewStartDate', 'NewEndDate']])
你能不能解釋一下什麼樣的手段「日期範圍內沒有差距」?我無法理解這個問題。謝謝。 –
我已更新我的帖子,以包含有關「無間隙」的更多詳細信息,以嘗試澄清此問題。 – Netbrian