我正在尝试找到一个很好的干净的Python / Pandas方法来获取以下数据帧:
ID Date_Field Category
12345 01/01/12 AAAA
12345 01/02/12 AAAA
12345 01/03/12 AAAA
12345 01/04/12 BBBB
12345 01/05/12 BBBB
12345 01/06/12 BBBB
2468 01/01/12 AAAA
2468 01/02/12 AAAA
2468 01/03/12 AAAA
2468 01/04/12 BBBB
2468 01/05/12 BBBB
2468 01/06/12 BBBB
2468 01/07/12 BBBB
2468 01/08/12 CCCC
2468 01/09/12 CCCC
2468 01/10/12 AAAA
2468 01/11/12 AAAA
并将其转换为与此类似的数据框,即我有每个ID /类别的开始/结束日期,但有一点需要注意,如果日期之间存在日期差异,ID /类别组合可能会多次出现:
ID Start_Date End_Date Category
12345 01/01/12 01/03/12 AAAA
12345 01/04/12 01/06/12 BBBB
2468 01/01/12 01/03/12 AAAA
2468 01/10/12 01/11/12 AAAA
2468 01/04/12 01/07/12 BBBB
2468 01/08/12 01/09/12 CCCC
我知道我可以通过迭代和比较之前的行值来做到这一点,但我感觉有一个更清晰的方法。
答案 0 :(得分:3)
你可以groupby
。如果您只想要一个列,则可以执行以下操作:
>>> df.groupby(['ID','Category']).min()
Date_Field
ID Category
2468 AAAA 01/01/12
BBBB 01/04/12
CCCC 01/08/12
12345 AAAA 01/01/12
BBBB 01/04/12
并且你也可以做this answer:
>>> df.groupby(['ID','Category']).agg({'Date_Field' : [min, max]})
Date_Field
min max
ID Category
2468 AAAA 01/01/12 01/11/12
BBBB 01/04/12 01/07/12
CCCC 01/08/12 01/09/12
12345 AAAA 01/01/12 01/03/12
BBBB 01/04/12 01/06/12
修改强>
groupby
会产生DataFrame
与grouped columns as index,以禁用此添加as_index=False
:
>>> df.groupby(['ID','Category'], as_index=False).agg({'Date_Field' : [min, max]})
ID Category Date_Field
min max
0 2468 AAAA 01/01/12 01/11/12
1 2468 BBBB 01/04/12 01/07/12
2 2468 CCCC 01/08/12 01/09/12
3 12345 AAAA 01/01/12 01/03/12
4 12345 BBBB 01/04/12 01/06/12
编辑2 :
要使用相同的ID和类别分隔数据的不同时间间隔,我们必须添加新类别:
df['Cat2']=0
for i in range(2,len(df)):
if df['Category'].iloc[i]==df['Category'][i-1]:
df['Cat2'].iloc[i]=df['Cat2'].iloc[i-1]
else:
df['Cat2'].iloc[i]=df['Cat2'].iloc[i-1]+1
这个for循环创建一个新的Cat2
列,如果前一行(i-1)具有相同的Category
,它将具有相同的值,否则将创建一个新值(前一个+ 1) )。请注意,此方法完全取决于数据的顺序!
现在我们可以将其添加到groupby
类别:
>>> df.groupby(['ID','Category','Cat2'], as_index=False).agg({'Date_Field' : [min, max]})
ID Category Cat2 Date_Field
min max
0 2468 AAAA 2 01/01/12 01/03/12
1 2468 AAAA 5 01/10/12 01/11/12
2 2468 BBBB 3 01/04/12 01/07/12
3 2468 CCCC 4 01/08/12 01/09/12
4 12345 AAAA 0 01/01/12 01/03/12
5 12345 BBBB 1 01/04/12 01/06/12