Python 如何使用pandas识别边缘日期案例
我有一个如下所示的数据帧Python 如何使用pandas识别边缘日期案例,python,pandas,dataframe,datetime,pandas-groupby,Python,Pandas,Dataframe,Datetime,Pandas Groupby,我有一个如下所示的数据帧 df1 = pd.DataFrame({'person_id': [11,11,11,11,11,12,12,12,12,12,13,13,13,13,14,14,14,14,14], 'date_birth': ['12/31/1961','01/01/1961','10/21/1961','12/11/1961','02/11/1961',
df1 = pd.DataFrame({'person_id': [11,11,11,11,11,12,12,12,12,12,13,13,13,13,14,14,14,14,14],
'date_birth': ['12/31/1961','01/01/1961','10/21/1961','12/11/1961','02/11/1961',
'05/29/1967','01/29/1967','04/29/1967','03/19/1967','01/01/1957',
'12/31/1959','01/01/1959','01/01/1959','07/27/1959',
'01/01/1957','01/01/1957','12/31/1957','12/31/1958','01/01/1957']})
df1 = df1.melt('person_id', value_name='dates')
df1['dates'] = pd.to_datetime(df1['dates'])
我的目标是确定此数据框中的边缘情况
边缘情况定义为受试者的日期列中同时包含1月1日
和12月31日
。
例如,从示例数据框中,我们可以看到person_id=11
是一个边缘大小写,因为他在dates
列值中既有Jan 1st
又有Dec 31st
,而person_id=12不是一个边缘大小写,因为他没有Dec 31th
和Jan 1st
这就是我试过的
op_df = df1.groupby(['person_id'], sort=False).apply(lambda x: x.sort_values(['dates'], ascending=True)).reset_index(drop=True)
op_df['day'] = op_df.dates.dt.day
op_df['month'] = op_df.dates.dt.month
op_df['points'] = np.where(((op_df['day'] == 1) & (op_df['month'] == 1)) & ((op_df['day'] == 31) & (op_df['month'] == 12)),'edge','No')
但是上面的代码没有正确过滤。对于我的所有个人ID,它返回为No
我希望我的输出如下
这里的问题是不可能的日=1和月=1
与月底,需要通过链接或:
op_df = df1.sort_values(['person_id','dates'])
op_df['day'] = op_df.dates.dt.day
op_df['month'] = op_df.dates.dt.month
op_df['points'] = np.where(((op_df['day'] == 1) & (op_df['month'] == 1)) | ((op_df['day'] == 31) & (op_df['month'] == 12)),'edge','No')
如果需要两条边,则可以首先通过掩码创建两列,为countTrue
s值聚合sum
,并根据条件为第二列添加Edge
列-Yes
如果一列或第二列中至少有一列0
:
#instead groupby + sort_values use sort_values by 2 columns
op_df = df1.sort_values(['person_id','dates'], ascending=True)
day = op_df.dates.dt.day
month = op_df.dates.dt.month
op_df['1.1'] = (day == 1) & (month == 1)
op_df['31.12'] = (day == 31) & (month == 12)
op_df = op_df.groupby('person_id', as_index=False)[['1.1','31.12']].sum()
op_df.insert(1, 'Edge', np.where(op_df[['1.1','31.12']].eq(0).any(axis=1),'No','Yes'))
print (op_df)
person_id Edge 1.1 31.12
0 11 Yes 1 1
1 12 No 1 0
2 13 Yes 2 1
3 14 Yes 3 2