#python #python-3.x #pandas #dataframe
Вопрос:
У меня есть два кадра данных, упорядоченных по времени и времени, с использованием DatetimeIndex (метка времени), как показано ниже.
df1
timestamp price side
2021-08-27 12:45:00.475100160 00:00 47.34
2021-08-27 12:45:00.475100160 00:00 47.02
2021-08-27 12:45:00.488067957 00:00 47.18
2021-08-27 12:45:00.779297294 00:00 47.26
2021-08-27 12:45:00.779297294 00:00 47.27
df2
timestamp bid_price ask_price
2021-08-27 12:44:59.740064471 00:00 47.08 47.34
2021-08-27 12:45:00.475100160 00:00 47.02 47.34
2021-08-27 12:45:00.914411789 00:00 47.02 47.26
2021-08-27 12:45:00.915470114 00:00 47.02 47.34
Мне нужно сравнить индекс времени каждой строки в первом кадре данных (df1) с индексом времени даты второго кадра данных (df2). Первая строка в df2, которая имеет значение datetime, равное или меньшее значение datetimeindex строки в df1, будет использоваться для оценки столбцов df2.bid_price и df2.ask_price по сравнению со столбцом df1.цена. Если df1.цена == df2.bid_price, добавьте «Ставка» в столбец df1.side. Если df1.цена == df2.ask_price, добавьте » Ask » в столбец df1.side. Если df1.цена находится между dff2.ask_price и df2.bid_price, добавьте «Внутри» в столбец df1.side, иначе добавьте «Снаружи» в столбец df1.side.
Мой приведенный ниже код-наименее эффективный способ сделать это, выполнив итерацию по каждой строке df1 и сравнив ее с df2. Короче говоря, это занимает целую вечность, когда я начинаю просматривать что-либо более 10-20 тысяч строк. Я искал более эффективные способы сделать это.
for x in range(len(df1)):
price = df1.price.iloc[x]
quote = df2[(df1.index[x] >= df2.index)][['bid_price','ask_price']].iloc[-1]
if price == quote.bid_price:
df1.side.iloc[x] = 'Bid'
elif price == quote.ask_price:
df1.side.iloc[x] = 'Ask'
elif (price > quote.bid_price) amp; (price < quote.ask_price):
df1.side.iloc[x] = 'Inside'
else:
df1.side.iloc[x] = 'Outside'
Комментарии:
1. Я думаю, что вы могли бы использовать индекс из df1, чтобы найти нужную строку в df2 с помощью обратной интерполяции, а затем оттуда вы можете напрямую соединить их. Я попытаюсь откопать что-нибудь похожее, что я сделал некоторое время назад
2. Благодаря Дэвиду я надеюсь получить предложения о том, как значительно ускорить это, так как я использую время от времени 100 тыс. точек данных.
Ответ №1:
Вот рабочее решение, использующее pandas.merge_asof
для объединения временных меток и numpy.select
соответствия различным условиям:
import numpy as np
df3 = pd.merge_asof(df1, df2, on='timestamp', direction='backward')
df3['side'] = np.select([df3['price']==df3['bid_price'],
df3['price']==df3['ask_price'],
df3['price'].between(df3['bid_price'], df3['ask_price'])
],
['Bid', 'Ask', 'Inside'],
default='Outside'
)
выход:
>>> df3
timestamp price side bid_price ask_price
0 2021-08-27 12:45:00.475100160 00:00 47.34 Ask 47.02 47.34
1 2021-08-27 12:45:00.475100160 00:00 47.02 Bid 47.02 47.34
2 2021-08-27 12:45:00.488067957 00:00 47.18 Inside 47.02 47.34
3 2021-08-27 12:45:00.779297294 00:00 47.26 Inside 47.02 47.34
4 2021-08-27 12:45:00.779297294 00:00 47.27 Inside 47.02 47.34
ПРИМЕЧАНИЕ. при необходимости вы можете удалить промежуточные столбцы: df3.drop(['bid_price', 'ask_price'], axis=1)
Комментарии:
1. спасибо, мозуэй. Это намного быстрее. Я подожду день или около того, чтобы посмотреть, есть ли у кого-нибудь еще какой-либо дополнительный ответ, прежде чем я приму и подам голос.