Используйте DataFrame.drop_duplicates
с Series.shift
из Series
после преобразования Rank
в индекс, поэтому возможно последнее использование Series.map
:
df['DateTime'] = pd.to_datetime(df['DateTime'])
s = df.drop_duplicates('Rank').set_index('Rank')['DateTime'].shift()
df['Previous Datetime'] = df['Rank'].map(s)
print (df)
DateTime Previous Datetime Rank
0 2019-09-06 00:00:00 NaT 1
1 2019-09-10 00:00:00 2019-09-06 00:00:00 2
2 2019-09-13 00:00:00 2019-09-10 00:00:00 3
3 2019-09-17 00:00:00 2019-09-13 00:00:00 4
4 2019-09-20 10:00:00 2019-09-17 00:00:00 5
5 2019-09-24 00:00:00 2019-09-20 10:00:00 6
6 2019-09-27 10:21:00 2019-09-24 00:00:00 7
7 2019-10-01 00:00:00 2019-09-27 10:21:00 8
8 2019-10-01 00:00:00 2019-09-27 10:21:00 8
РЕДАКТИРОВАТЬ:
df = df.drop('Elapsed Time Previous', axsi=1)
df['DateTime'] = pd.to_datetime(df['DateTime'])
# df['Elapsed Time Previous'] =
s = (df.drop_duplicates(['Rank','Name', 'ID'])
.set_index(['Name', 'ID', 'Rank'])['DateTime']
.unstack()
.shift(axis=1)
.stack()
.rename('Elapsed Time Previous'))
df = df.join(s, on=['Name','ID','Rank'])