test = pd.DataFrame({'ID':[1,2,3,3,4,4],'ID2':[1,1,1,1,2,1]\
,'dts1':['2016-1-25','2016-1-25','2016-1-25','2016-2-20','2016-1-25','2016-2-20']
,'dts2':['2016-1-27','2016-1-27','2016-1-27','2016-2-24','2016-1-27','2016-2-24']})
我有一个数据框,例如:
ID ID2 dts1 dts2
0 1 1 2016-1-25 2016-1-27
1 2 1 2016-1-25 2016-1-27
2 3 1 2016-1-25 2016-1-27
3 3 1 2016-2-20 2016-2-24
4 4 2 2016-1-25 2016-1-27
5 4 1 2016-2-20 2016-2-24
我希望1)具有相同ID的行2)具有不同ID2的行3)在具有相同ID的下一行的下一个dts1的30天内具有dts2 ...
对于此数据框,我需要最后两行(其中ID =下一个ID,ID2!=下一个ID2和dts2 <下一个dts1 + 30天
****编辑***
ts_df[ts_df.groupby(['ID']).apply(lambda x: ((x['dts1'].shift(-1)-x['dts2']<=pd.Timedelta('30days'))\
&(x['ID2'].shift(-1)!=x['ID2']))|\
((x['dts1']-x['dts2'].shift(1)<=pd.Timedelta('30days'))\
&(x['ID2']!=x['ID2'].shift(1)))).values]
我发现唯一起作用的是上面的^
它非常慢(在我的数据集上为22分钟),所以任何改进将不胜感激。
答案 0 :(得分:0)
df["alike"] = df.apply(
lambda row: "watermelon" if "watermelon" in row["name"] and "melon" in row["alike"] else row["alike"],
axis=1
)
我在这里将test['dts1'] = pd.to_datetime(test['dts1'])
test['dts2'] = pd.to_datetime(test['dts2'])
def get_what_you_need(df):
mask1 = df[df.duplicated(subset='ID', keep=False)]
mask2 = mask1.drop_duplicates(subset=['ID', 'ID2'], keep=False).reset_index(drop=True)
idx = 0
if len(df) >= 2:
mask3 = (mask2.loc[idx + 1, 'dts1'] - mask2.loc[idx, 'dts2']) < pd.Timedelta(days = 30)
else:
return None
if mask3:
return mask2
else:
return None
get_what_you_need(test)
和idx
作为常量。如果需要,可以将days
和idx
设置为函数的参数。