Как объединить набор данных Pandas в себя, основываясь на условии и групповом - PullRequest
0 голосов
/ 07 мая 2018

Для лучшей иллюстрации рассмотрим следующую иллюстрацию SQL: Таблица StockPrices, BarSeqId - это порядковый номер, в котором каждое приращение является информацией со следующей минуты торговли.

Цель, которую нужно достичь в кадре данных панд, - преобразовать эти данные:

StockPrice    BarSeqId LongProfitTarget
105           0           109
100           1           105
103           2           107
103           3           108
104           4           110
105           5           113

в эти данные:

StockPrice    BarSeqId    LongProfitTarget  TargetHitBarSeqId
106           0           109               Nan
100           1           105               3 
103           2           107               5
105           3           108               Nan
104           4           110               Nan
107           5           113               Nan

для создания нового столбца, который описывает, в какой самый короткий последовательный период времени цель по цене будет достигнута в будущем по сравнению с текущим периодом времени

Вот как этого можно достичь в SQL:

SELECT S1.StockPrice, S1.BarSeqId, S1.LongProfitTarget, 
   min(S2.BarSeqId) as TargetHitBarSeqId
FROM StockPrices S1
   left outer join StockPrices S2 on S1.BarSeqId<s2.BarSeqId and 
  S2.StockPrice>=S1.LongProfitTarget
GROUP BY S1.StockPrice, S1.BarSeqId, S1.LongProfitTarget

Я бы хотел, чтобы ответ был следующим:

 someDataFrame['TargetHitBarSeqId'] = (pandas expression here ...**

предположим, что у someDataFrame уже есть столбцы: StockPrice, BarSeqId, LongProfitTarget

данные отредактированы для иллюстрации случая поэтому во втором ряду результат должен быть

100           1           105               3 

и НЕ

100           1           105               0 

с 3, а не 0 происходит после 1.

Важно, чтобы рассматриваемый barseq имел место в будущем (больше, чем текущий BarSeq)

df = pd.DataFrame({'StockPrice':[105,100,103,105,104,107],'BarSeqId':[0,1,2,3,4,5],
          'LongProfitTarget':[109,105,107,108,110,113]})
def get_barseqid(longProfitTarget):
    try:
        idx = df.StockPrice[df.StockPrice >= longProfitTarget].index[0]
        return df.iloc[idx].BarSeqId
    except:
        return np.nan

df['TargetHitBarSeqId'] = df.apply(lambda row: get_barseqid(row['LongProfitTarget']), axis=1)

Ответы [ 3 ]

0 голосов
/ 07 мая 2018
from pathlib import Path
import pandas as pd
from itertools import islice
import numpy as np

df = pd.DataFrame({'StockPrice':[105,100,103,105,104,107],'BarSeqId':[0,1,2,3,4,5],
              'LongProfitTarget':[109,105,107,108,110,113]})
def get_barseqid(longProfitTarget,barseq):
    try:
        idx = df[(df.StockPrice >= longProfitTarget) & (df.BarSeqId>barseq)].index[0]
        return df.iloc[idx].BarSeqId
    except:
        return np.nan

df['TargetHitBarSeqId'] = df.apply(lambda row: get_barseqid(row['LongProfitTarget'], row['BarSeqId']), axis=1)
df

Ключевое недоразумение для меня заключалось в необходимости использовать & оператор вместо обычного 'или'

0 голосов
/ 07 мая 2018

Предполагая, что данные являются управляемыми, рассмотрим перекрестное объединение с последующим фильтром и groupby, который будет повторять запрос SQL:

cdf = pd.merge(df.assign(key=1), df.assign(key=1), on='key', suffixes=['','_'])\
            .query('(BarSeqId < BarSeqId_) & (LongProfitTarget <= StockPrice_)')\
            .groupby(['StockPrice', 'BarSeqId', 'LongProfitTarget'])['BarSeqId_'].min()

print(cdf)
# StockPrice  BarSeqId  LongProfitTarget
# 100         1         105                 3
# 103         2         107                 5
# Name: BarSeqId_, dtype: int64
0 голосов
/ 07 мая 2018

Вот одно из решений:

import pandas as pd
import numpy as np

df = <your input data frame>

def get_barseqid(longProfitTarget):
    try:
        idx = df.StockPrice[df.StockPrice >= longProfitTarget].index[0]
        return df.iloc[idx].BarSeqId
    except:
        return np.nan

df['TargetHitBarSeqId'] = df.apply(lambda row: get_barseqid(row['LongProfitTarget']), axis=1)

Выход:

   StockPrice  BarSeqId  LongProfitTarget  TargetHitBarSeqId
0         100         1               105                3.0
1         103         2               107                5.0
2         105         3               108                NaN
3         104         4               110                NaN
4         107         5               113                NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...