Python 在包含日期列的列中查找更改
我有一个熊猫数据框,我在基于一些标准的融合和过滤后得到的,它看起来像这样Python 在包含日期列的列中查找更改,python,pandas,Python,Pandas,我有一个熊猫数据框,我在基于一些标准的融合和过滤后得到的,它看起来像这样 P D A 2018-01-01 A 2018-01-02 A 2018-01-03 B 2018-01-03 A 2018-01-04 B 2018-01-04 A 2018-01-05 A 2018-01-06 A 2018-01-07 B 2018-01-07 从这个数据帧,我想制作一些像这样的数据帧 P D1
P D
A 2018-01-01
A 2018-01-02
A 2018-01-03
B 2018-01-03
A 2018-01-04
B 2018-01-04
A 2018-01-05
A 2018-01-06
A 2018-01-07
B 2018-01-07
从这个数据帧,我想制作一些像这样的数据帧
P D1 D2
A 2018-01-01 2018-01-02
A, B 2018-01-03 2018-01-04
A 2018-01-05 2018-01-06
A, B 2018-01-07 -
从数据中的p
列中,我们可以看到从2018-01-01
到2018-01-02
只有一个值a
,因此我们将在结果数据框中的第一行显示为a,2018-01-01,2018-01-02
同样,从2018-01-03
到2018-01-04
之间有A和B,因此在数据框中有第二行
如何在熊猫中高效地执行此操作?您可以尝试以下操作:
import pandas as pd
import datetime as dt
#generate dataframe
letters = ['A', 'A', 'A', 'B', 'A', 'B', 'A', 'A', 'A', 'B']
dates = [dt.date(2018,1,1), dt.date(2018,1,2), dt.date(2018,1,3), dt.date(2018,1,3), dt.date(2018,1,4), dt.date(2018,1,4), dt.date(2018,1,5), dt.date(2018,1,6), dt.date(2018,1,7), dt.date(2018,1,7)]
df = pd.DataFrame(zip(letters, dates), columns = ['P','D'])
#生成日期对
开始日期=df.iloc[0]['D']
结束日期=df.iloc[-1]['D']
日期=[范围(0,(结束日期-开始日期)。天,2)内x的开始日期+dt.timedelta(天=x)]
date\u pairs=zip(日期,[date+dt.timedelta(days=1)表示日期中的日期])
#生成输出数据帧
l=[]
对于date1,date2(日期对):
p=df[(df['D']>=date1)和(df['D']我已经制定了一个特别的解决方案,我知道它根本不是最优的。希望有人能提出一些改进和增强建议
a_df = pd.read_clipboard()
s = a_df.groupby(by=['D'])['P'].unique().apply('+'.join).reset_index()
s['s_1'] = s.P.eq(s.P.shift(-1))
s['s_2'] = s.P.eq(s.P.shift(1))
a1 = s.loc[(s['s_1'] == True) & (s['s_2'] == False)].index.values
a2 = s.loc[(s['s_1'] == False) & (s['s_2'] == True)].index.values
count = 1
s['Flag'] = 0
for x,y in zip(a1, a2):
s.loc[x:y, 'Flag'] = count
count += 1
s.groupby(['Flag'], as_index=False).agg({'P' : 'first', 'D' : ['min', 'max']}).sort_values([('D', 'min')])
Flag P D
first min max
1 1 A 2018-01-01 2018-01-02
2 2 A+B 2018-01-03 2018-01-04
3 3 A 2018-01-05 2018-01-06
0 0 A+B 2018-01-07 2018-01-07
a_df = pd.read_clipboard()
s = a_df.groupby(by=['D'])['P'].unique().apply('+'.join).reset_index()
s['s_1'] = s.P.eq(s.P.shift(-1))
s['s_2'] = s.P.eq(s.P.shift(1))
a1 = s.loc[(s['s_1'] == True) & (s['s_2'] == False)].index.values
a2 = s.loc[(s['s_1'] == False) & (s['s_2'] == True)].index.values
count = 1
s['Flag'] = 0
for x,y in zip(a1, a2):
s.loc[x:y, 'Flag'] = count
count += 1
s.groupby(['Flag'], as_index=False).agg({'P' : 'first', 'D' : ['min', 'max']}).sort_values([('D', 'min')])
Flag P D
first min max
1 1 A 2018-01-01 2018-01-02
2 2 A+B 2018-01-03 2018-01-04
3 3 A 2018-01-05 2018-01-06
0 0 A+B 2018-01-07 2018-01-07