Pandas DF реструктурировать - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь реструктурировать pandas df. У меня есть столбцы с именами биржевых символов 'SPY,' JPM ',' AAPL, 'GLD', и у каждого столбца есть скорректированные данные закрытия. Я индексирую с датами. Я хочу создать многоиндексный df с этим именем с именами в качестве первого уровня и датами в качестве второго уровня. Я сделал это уродливым окольным путем, но мне было любопытно, могу ли я просто использовать pivot или что-то еще для достижения этой цели. Я просматривал общие функции PD и документацию по изменению формы PD df, но я не могу соединить точки, чтобы решить эту проблему.

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

>>>sym_df = get_data(symbol, pd.date_range(sd, ed))  # automatically adds SPY
>>>print(sym_df)

               SPY    JPM    AAPL     GLD
2010-01-04  108.27  40.87  213.10  109.80
2010-01-05  108.56  41.67  213.46  109.70
2010-01-06  108.64  41.89  210.07  111.51
2010-01-07  109.10  42.72  209.68  110.82
2010-01-08  109.46  42.62  211.07  111.37
...            ...    ...     ...     ...
2011-12-23  125.19  32.84  401.61  156.31
2011-12-27  125.29  32.31  404.79  154.91
2011-12-28  123.64  31.94  400.92  151.03
2011-12-29  124.92  32.69  403.39  150.34
2011-12-30  124.31  32.53  403.27  151.99

[504 rows x 4 columns]

>>>data = {}  
>>>for sym in sym_df.columns:
>>>  sym_df = sym_df.rename(columns={sym: 'Adj_Close_Price'})
>>>  data[sym] = sym_df['Adj_Close_Price']
>>>  sym_df = sym_df.drop(['Adj_Close_Price'], axis=1)
>>>df = pd.concat(data.values(), keys=data.keys())
>>>df = df.reset_index()
>>>df = df.rename(columns={'level_0': 'Symbol', 'level_1': "Date"})
>>>df.set_index(['Symbol', 'Date'], inplace=True)
>>>df.sort_index(inplace=True)

>>>df = df.fillna(method='ffill')
>>>df = df.fillna(method='bfill')
>>>print(df)
                   Adj_Close_Price
Symbol Date
AAPL   2010-01-04           213.10
       2010-01-05           213.46
       2010-01-06           210.07
       2010-01-07           209.68
       2010-01-08           211.07
...                            ...
SPY    2011-12-23           125.19
       2011-12-27           125.29
       2011-12-28           123.64
       2011-12-29           124.92
       2011-12-30           124.31

[2016 rows x 1 columns] 

Ответы [ 2 ]

0 голосов
/ 29 апреля 2020

Предполагая, что "data" - это ваш начальный df (с датами в индексе)

data['Date'] = data.index
data = data.reset_index(level = 0)

data = pd.melt(data, id_vars = ['Date'], value_vars=['SPY', 'JPM', 'AAPL', 'GLD'])

data = data.set_index(['variable', 'Date'])
0 голосов
/ 29 апреля 2020

Вы можете попробовать:

import pandas as pd
import io

data_string = """DATE;SPY;JPM;AAPL;GLD
2010-01-04;108.27;40.87;213.10;109.80
2010-01-04;108.56;41.67;213.46;109.70
2010-01-05;108.64;41.89;210.07;111.51
2010-01-05;109.10;42.72;209.68;110.82
2010-01-06;109.46;42.62;211.07;111.37
2011-12-23;125.19;32.84;401.61;156.31
2011-12-23;125.29;32.31;404.79;154.91
2011-12-28;123.64;31.94;400.92;151.03
2011-12-29;124.92;32.69;403.39;150.34
2011-12-30;124.31;32.53;403.27;151.99
"""

data = io.StringIO(data_string)
df = pd.read_csv(data, sep=";")

df = pd.melt(df, id_vars=['DATE'], value_vars=['SPY', 'JPM', 'AAPL', 'GLD'], var_name='STOCK', value_name='CLOSE')
df['DATE'] = pd.DatetimeIndex(df['DATE'])
df.set_index(['STOCK', 'DATE'], inplace=True)

print(df)

Результат:

                   CLOSE
STOCK DATE              
SPY   2010-01-04  108.27
      2010-01-04  108.56
      2010-01-05  108.64
      2010-01-05  109.10
      2010-01-06  109.46
      2011-12-23  125.19
      2011-12-23  125.29
      2011-12-28  123.64
      2011-12-29  124.92
      2011-12-30  124.31
JPM   2010-01-04   40.87
      2010-01-04   41.67
      2010-01-05   41.89
      2010-01-05   42.72
      2010-01-06   42.62
      2011-12-23   32.84
      2011-12-23   32.31
      2011-12-28   31.94
      2011-12-29   32.69
      2011-12-30   32.53
AAPL  2010-01-04  213.10
      2010-01-04  213.46
      2010-01-05  210.07
      2010-01-05  209.68
      2010-01-06  211.07
      2011-12-23  401.61
      2011-12-23  404.79
      2011-12-28  400.92
      2011-12-29  403.39
      2011-12-30  403.27
GLD   2010-01-04  109.80
      2010-01-04  109.70
      2010-01-05  111.51
      2010-01-05  110.82
      2010-01-06  111.37
      2011-12-23  156.31
      2011-12-23  154.91
      2011-12-28  151.03
      2011-12-29  150.34
      2011-12-30  151.9
...