#python #pandas
#python #pandas
Вопрос:
Я знаком с тем, как объединить / объединить два фрейма данных Pandas следующим образом:
result = pd.merge(user_usage,
user_device[['use_id', 'platform', 'device']],
on='use_id',
how='right')
Однако я не знаю, как мне выполнить самосоединение таблицы:
id rank ts
1 1 2015-11-01
1 2 2015-11-03
1 3 2015-11-07
где я хочу сравнить временную метку каждого идентификатора-ранга со следующей.
В синтаксисе SQL и Scala это просто. В SQL я бы просто сделал что-то вроде (в псевдокоде):
SELECT *
FROM df a
LEFT JOIN df b
ON a.id = b.id amp; (a.rank 1) = b.rank;
В pd.merge
синтаксисе я никогда не видел такого примера и до сих пор не могу его найти.
Чтобы было ясно, я ищу:
id rank ts ts_2 time_since_previous_obs
1 1 2015-11-01 <null> 0
1 2 2015-11-03 2015-11-01 2
1 3 2015-11-07 2015-11-03 4
Возможно ли это с помощью Python Pandas merge
или join
синтаксиса? Есть ли другой более разумный способ?
Комментарии:
1. попробуйте
df['last_obs_since'] = df.apply(lambda row,cmp: row['ts']-cmp.loc[row.name]['ts'],axis=1,args=[df.shift(1)])
илиdf['last_obs_since'] = df['ts'] - df.shift(1)['ts']
Ответ №1:
Ну, вы можете изменить ранг перед слиянием:
(df.merge(df.assign(rank=df['rank'] - 1),
on=['id','rank'], how='left')
.assign(last_obs_since=lambda x: x['ts_y'] - x['ts_x'])
)
Вывод:
id rank ts_x ts_y last_obs_since
0 1 1 2015-11-01 2015-11-02 1 days
1 1 2 2015-11-02 2015-11-03 1 days
2 1 3 2015-11-03 NaT NaT
Ответ №2:
#create a list from ts and shift by one to make ts2
ts2 =df["ts"][:-1].tolist()
ts2.insert(0,None)
#append list to dataframe
df["ts2"] = ts2
#calculate difference
df["diff"] = df["ts"] - df["ts2"]
print(df)
вывод:
Ответ №3:
Также должно работать следующее,
df['ts2'] = df.shift(1)['ts']
df['last_obs_since'] = df['ts'] - df['ts2']