Фрейм данных groupby() в MultiIndex затем применяется к нескольким столбцам, что приводит к проблемам с трансляцией

#pandas #dataframe #data-science #ta-lib

#pandas #dataframe #наука о данных #ta-lib

Вопрос:

Это настройка:

 arrays = [["2010-01-01","2010-01-01","2010-01-02","2010-01-02","2010-01-03","2010-01-03"],
                 ["MSFT", "AAPL", "MSFT", "AAPL","MSFT", "AAPL"]]

tuples = list(zip(*arrays))

index = pd.MultiIndex.from_tuples(tuples, names=["date", "symbol"])

df = pd.DataFrame(data=np.random.randn(6, 4), index=index, columns=["high", "low", "open", "close"])

def fn_sum(close, high, low):
    return close high low

def fn_plus(close):
        return close 1
 

DF выглядит следующим образом:

 date       symbol   high        low        open        close

2010-01-01  MSFT  1.144042   0.889603   -0.193715   1.005927
            AAPL  0.433530  -0.291510    1.420505   0.326206
2010-01-02  MSFT -1.509419  -0.273476   -0.620735  -0.205946
            AAPL  0.454401  -0.085008    0.686485   1.309894
2010-01-03  MSFT  1.487588  -0.777500   -0.218993  -1.242664
            AAPL -0.456024  -0.819463   -2.224953   1.263124
 

Я хочу использовать функции технического анализа для всех символов с помощью groupby(), apply() следующим образом:

df[«1″] = df.groupby(уровень =»символ»).применить(лямбда x: fn_sum(x[«закрыть»], x[«высокий»], x[«низкий»]))

Это приводит к ошибке широковещательной передачи:

 ValueError: operands could not be broadcast together with shapes (6,2) (3,) (6,2)
 

Однако выполнение того же самого для отдельного столбца работает:

df[«2″] = df.groupby(уровень=»символ»).закрыть.применить(лямбда x: fn_plus(x))

Вопросы:

  • Итак, как мне заставить это работать при использовании apply для нескольких столбцов и объединении их обратно в фрейм данных без проблем с трансляцией?
  • Также я очень благодарен за лучшую реализацию, которая работает с многоиндексными DFS, как описано выше.

Для получения дополнительной информации: я хочу использовать функции технического анализа из пакета TA-lib. См.: https://mrjbq7.github.io/ta-lib/func_groups/volatility_indicators.html

Функции выглядят следующим образом (например)::

ATR(высокий, низкий, близкий[, timeperiod=?])

Средний истинный диапазон (Индикаторы волатильности)

Входные данные: цены: [‘высокие’, ‘низкие’, ‘близкие’] Параметры: временной интервал: 14 Выходы: реальные

Я получаю ту же ошибку трансляции, что и выше в надуманном примере.

Ответ №1:

Если необходимо несколько столбцов, перейдите к использованию функции DataFrame.join или DataFrame.assign :

 s = (df.groupby(level="symbol", group_keys=False)
       .apply(lambda x: fn_sum(x["close"], x["high"], x["low"])))
df = df.join(s.rename('new'))
#alternative
#df = df.assign(new=s)
print (df)
                       high       low      open     close       new
date       symbol                                                  
2010-01-01 MSFT   -1.085631  0.997345  0.282978 -1.506295 -1.594580
           AAPL   -0.578600  1.651437 -2.426679 -0.428913  0.643924
2010-01-02 MSFT    1.265936 -0.866740 -0.678886 -0.094709  0.304487
           AAPL    1.491390 -0.638902 -0.443982 -0.434351  0.418136
2010-01-03 MSFT    2.205930  2.186786  1.004054  0.386186  4.778903
           AAPL    0.737369  1.490732 -0.935834  1.175829  3.403930
 

Если использовать только один столбец GroupBy.transform и указать столбец после groupby :

 df['new1'] = df.groupby(level="symbol")['close'].transform(fn_plus)
print (df)
                       high       low      open     close      new1
date       symbol                                                  
2010-01-01 MSFT   -1.085631  0.997345  0.282978 -1.506295 -0.506295
           AAPL   -0.578600  1.651437 -2.426679 -0.428913  0.571087
2010-01-02 MSFT    1.265936 -0.866740 -0.678886 -0.094709  0.905291
           AAPL    1.491390 -0.638902 -0.443982 -0.434351  0.565649
2010-01-03 MSFT    2.205930  2.186786  1.004054  0.386186  1.386186
           AAPL    0.737369  1.490732 -0.935834  1.175829  2.175829