Как извлечь конкретные данные из мультииндексного фрейма данных (данные по акциям Yahoo) - PullRequest
0 голосов
/ 24 сентября 2018

Может ли кто-нибудь дать мне быстрый / понятный урок по захвату определенных точек данных в мультииндексном фрейме данных ниже?Я смотрел учебники весь день, но ни один из них не был очень полезным.Это должно быть просто для тех, кто знает панд.

Как я могу сделать следующее:

  1. Извлечь 'close' из 'AAPL' в последнюю датуфрейм данных

  2. Если «закрыто»> «открыто» из «AAPL» на конкретную дату, извлеките все данные для «AAPL» и добавьте в новый фрейм данных

  3. Добавить новый столбец для каждого символа (AAPL, FB), который помечен как «диапазон» и является «высоким» - «низким» для каждого дня

.

symbol      AAPL                                                FB
ohlcv       open    high    low     close   adj     volume      open    high    low     close   adj     volume
      Date                                              
2018-09-17  222.15  222.95  217.27  217.88  217.88  37195100    161.92  162.06  159.77  160.58  160.58  21005300
2018-09-18  217.79  221.85  217.12  218.24  218.24  31571700    159.39  161.76  158.87  160.30  160.30  22465200
2018-09-19  218.50  219.62  215.30  218.37  218.37  27123800    160.08  163.44  159.48  163.06  163.06  19629000
2018-09-20  220.24  222.28  219.15  220.03  220.03  26460800    164.50  166.45  164.47  166.02  166.02  18824200
2018-09-21  220.78  221.36  217.29  217.66  217.66  96246748    166.64  167.25  162.81  162.93  162.93  25956794

Вот словарь Dataframe в качестве одного из запрошенных комментариев,

df = pd.DataFrame({('AAPL', 'adj_close'): {
  pd.Timestamp('2018-01-02 00:00:00'): 170.3,
  pd.Timestamp('2018-01-03 00:00:00'): 170.27,
  pd.Timestamp('2018-01-04 00:00:00'): 171.07,
  pd.Timestamp('2018-01-05 00:00:00'): 173.01,
  pd.Timestamp('2018-01-08 00:00:00'): 172.37},
 ('AAPL', 'close'): {
  pd.Timestamp('2018-01-02 00:00:00'): 172.26,
  pd.Timestamp('2018-01-03 00:00:00'): 172.23,
  pd.Timestamp('2018-01-04 00:00:00'): 173.03,
  pd.Timestamp('2018-01-05 00:00:00'): 175.0,
  pd.Timestamp('2018-01-08 00:00:00'): 174.35},
 ('AAPL', 'high'): {
  pd.Timestamp('2018-01-02 00:00:00'): 172.3,
  pd.Timestamp('2018-01-03 00:00:00'): 174.55,
  pd.Timestamp('2018-01-04 00:00:00'): 173.47,
  pd.Timestamp('2018-01-05 00:00:00'): 175.37,
  pd.Timestamp('2018-01-08 00:00:00'): 175.61},
 ('AAPL', 'low'): {
  pd.Timestamp('2018-01-02 00:00:00'): 169.26,
  pd.Timestamp('2018-01-03 00:00:00'): 171.96,
  pd.Timestamp('2018-01-04 00:00:00'): 172.08,
  pd.Timestamp('2018-01-05 00:00:00'): 173.05,
  pd.Timestamp('2018-01-08 00:00:00'): 173.93},
 ('AAPL', 'open'): {
  pd.Timestamp('2018-01-02 00:00:00'): 170.16,
  pd.Timestamp('2018-01-03 00:00:00'): 172.53,
  pd.Timestamp('2018-01-04 00:00:00'): 172.54,
  pd.Timestamp('2018-01-05 00:00:00'): 173.44,
  pd.Timestamp('2018-01-08 00:00:00'): 174.35},
 ('AAPL', 'volume'): {
  pd.Timestamp('2018-01-02 00:00:00'): 25555900,
  pd.Timestamp('2018-01-03 00:00:00'): 29517900,
  pd.Timestamp('2018-01-04 00:00:00'): 22434600,
  pd.Timestamp('2018-01-05 00:00:00'): 23660000,
  pd.Timestamp('2018-01-08 00:00:00'): 20567800},
 ('FB', 'adj_close'): {
  pd.Timestamp('2018-01-02 00:00:00'): 181.42,
  pd.Timestamp('2018-01-03 00:00:00'): 184.67,
  pd.Timestamp('2018-01-04 00:00:00'): 184.33,
  pd.Timestamp('2018-01-05 00:00:00'): 186.85,
  pd.Timestamp('2018-01-08 00:00:00'): 188.28},
 ('FB', 'close'): {
  pd.Timestamp('2018-01-02 00:00:00'): 181.42,
  pd.Timestamp('2018-01-03 00:00:00'): 184.67,
  pd.Timestamp('2018-01-04 00:00:00'): 184.33,
  pd.Timestamp('2018-01-05 00:00:00'): 186.85,
  pd.Timestamp('2018-01-08 00:00:00'): 188.28},
 ('FB', 'high'): {
  pd.Timestamp('2018-01-02 00:00:00'): 181.58,
  pd.Timestamp('2018-01-03 00:00:00'): 184.78,
  pd.Timestamp('2018-01-04 00:00:00'): 186.21,
  pd.Timestamp('2018-01-05 00:00:00'): 186.9,
  pd.Timestamp('2018-01-08 00:00:00'): 188.9},
 ('FB', 'low'): {
  pd.Timestamp('2018-01-02 00:00:00'): 177.55,
  pd.Timestamp('2018-01-03 00:00:00'): 181.33,
  pd.Timestamp('2018-01-04 00:00:00'): 184.1,
  pd.Timestamp('2018-01-05 00:00:00'): 184.93,
  pd.Timestamp('2018-01-08 00:00:00'): 186.33},
 ('FB', 'open'): {
  pd.Timestamp('2018-01-02 00:00:00'): 177.68,
  pd.Timestamp('2018-01-03 00:00:00'): 181.88,
  pd.Timestamp('2018-01-04 00:00:00'): 184.9,
  pd.Timestamp('2018-01-05 00:00:00'): 185.59,
  pd.Timestamp('2018-01-08 00:00:00'): 187.2},
 ('FB', 'volume'): {
  pd.Timestamp('2018-01-02 00:00:00'): 18151900,
  pd.Timestamp('2018-01-03 00:00:00'): 16886600,
  pd.Timestamp('2018-01-04 00:00:00'): 13880900,
  pd.Timestamp('2018-01-05 00:00:00'): 13574500,
  pd.Timestamp('2018-01-08 00:00:00'): 17994700}})

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

IIUC,

  1. Извлечение 'close' из 'AAPL' в последнюю дату кадра данных

Просто получите максимальную датувыполнив df.index.max() и выберите AAPL / закрыть

df.loc[df.index.max(), ('AAPL', 'close')]
Если 'close' является> 'open' из 'AAPL' на определенную дату, извлеките все данные для 'AAPL' и добавьте в новый фрейм данных

В основном, если вы фильтруете, используя mask, возвращается data frame.Поэтому нет необходимости «добавлять к другому фрейму данных».

mask = df.loc[:, ('AAPL', 'open')] > df.loc[:, ('AAPL', 'close')]
df.loc[mask[mask].index, ('AAPL')]
Добавить новый столбец для каждого символа (AAPL, FB), который помечен как «диапазон» и является «высоким» - «низким» для каждого дня

Выэто можно сделать, просто выбрав столбцы (ticker, info), где ticker будет AAPL, FB, ... и info будет high, close, ..., а затем присоединиться.

r = df.loc[:, [('AAPL', 'high'), ('FB', 'high')]].sub(df.loc[:, [('AAPL', 'low'), ('FB', 'low')]].values).rename(columns={"high": "range"})
df = df.join(r).sort_index(1)

Обратите внимание, что вы работаетес MultiIndex столбцами.Это делает все операции более сложными для записи в коде.Вы можете подумать о переходе на столбец с одним индексом с новым столбцом с именем ticker' and values as AAPL , FB и т. Д.

Например, используя stack + reset_index, вы получите

df2 = df.stack(level=0).reset_index().rename(columns={'level_0': 'date', 'level_1': 'ticker'}).sort_values('ticker')

    date    ticker  adj_close   close   high    low     open    range   volume
0   2018-01-02  AAPL    170.30  172.26  172.30  169.26  170.16  3.04    25555900
2   2018-01-03  AAPL    170.27  172.23  174.55  171.96  172.53  2.59    29517900
4   2018-01-04  AAPL    171.07  173.03  173.47  172.08  172.54  1.39    22434600
6   2018-01-05  AAPL    173.01  175.00  175.37  173.05  173.44  2.32    23660000
8   2018-01-08  AAPL    172.37  174.35  175.61  173.93  174.35  1.68    20567800
1   2018-01-02  FB      181.42  181.42  181.58  177.55  177.68  4.03    18151900
3   2018-01-03  FB      184.67  184.67  184.78  181.33  181.88  3.45    16886600
5   2018-01-04  FB      184.33  184.33  186.21  184.10  184.90  2.11    13880900
7   2018-01-05  FB      186.85  186.85  186.90  184.93  185.59  1.97    13574500
9   2018-01-08  FB      188.28  188.28  188.90  186.33  187.20  2.57    17994700

Тогда, например, для вычисления range, это намного проще:

df2['range2'] = df2['high'] - df2['low']
0 голосов
/ 24 сентября 2018

Вы можете получить доступ к столбцам из мультииндексов напрямую с помощью индексации.Поскольку вы не опубликовали свой код данных, вы можете использовать эти фрагменты, чтобы проверить, работают ли они:

  1. df[('AAPL', 'close')] даст вам столбец 'close' в 'AAPL'.Вы можете отсортировать этот столбец по дате, чтобы извлечь последнюю дату.

    df.sort_values('Date', ascending=False).head(1)[('AAPL', 'close')]
    
  2. Чтобы сравнить и извлечь все данные 'AAPL', вы можете сделать что-то вроде:

    df[df[('AAPL', 'close')] > df[('AAPL', 'open')]]['AAPL']
    

    Добавьте также дату в условие фильтра.

  3. Возможно, существует более оптимальный способ, но он все еще может работать:

    for col in df.columns.levels[0]:
        df[(col, 'range')] = df[(col, 'high')] - df[(col, 'low')]
    

Вы можете добавить свои условия даты точно так же, как мы делаем в обычном фрейме данных.

...