Pandas column multi-index to rows

◇◆丶佛笑我妖孽 提交于 2021-02-11 07:10:21

问题


I'm using yfinance to download price history for multiple symbols, which returns a df with multiple indexes. For example:

import yfinance as yf
df = yf.download(tickers = ['AAPL', 'MSFT'], period = '2d')

A similar dataframe could be constructed without yfinance like:

import pandas as pd
pd.options.display.float_format = '{:.2f}'.format
import numpy as np

attributes = ['Adj Close', 'Close', 'High', 'Low', 'Open', 'Volume']
symbols = ['AAPL', 'MSFT']
dates = ['2020-07-23', '2020-07-24']
data = [[[371.38, 202.54], [371.38, 202.54], [388.31, 210.92], [368.04, 202.15], [387.99, 207.19], [49251100, 67457000]],
    [[370.46, 201.30], [370.46, 201.30], [371.88, 202.86], [356.58, 197.51 ], [363.95, 200.42], [46323800, 39799500]]]
data = np.array(data).reshape(len(dates),len(symbols) * len(attributes))

cols = pd.MultiIndex.from_product([attributes, symbols])
df = pd.DataFrame(data, index=dates, columns=cols)
df
           Adj Close           Close            High             Low            Open              Volume            
                AAPL    MSFT    AAPL    MSFT    AAPL    MSFT    AAPL    MSFT    AAPL    MSFT        AAPL        MSFT
2020-07-23    371.38  202.54  371.38  202.54  388.31  210.92  368.04  202.15  387.99  207.19  49251100.0  67457000.0
2020-07-24    370.46  201.30  370.46  201.30  371.88  202.86  356.58  197.51  363.95  200.42  46323800.0  39799500.0

Once I have this df, I want to restructure it so that I have a row for each symbol and date. I'm currently doing this by looping through a list of symbols and calling the API once each time, and appending the results. I'm sure there must be a more efficient way:

df = pd.DataFrame()
symbols = ['AAPL', 'MSFT']

for x in range(0, len(symbols)):
    symbol = symbols[x]
    result = yf.download(tickers = symbol, start = '2020-07-23', end = '2020-07-25')
    result.insert(0, 'symbol', symbol)
    df = pd.concat([df, result])

Example of the desired output:

df
           symbol        Open        High         Low       Close   Adj Close    Volume
Date                                                                                   
2020-07-23   AAPL  387.989990  388.309998  368.040009  371.380005  371.380005  49251100
2020-07-24   AAPL  363.950012  371.880005  356.579987  370.459991  370.459991  46323800
2020-07-23   MSFT  207.190002  210.919998  202.149994  202.539993  202.539993  67457000
2020-07-24   MSFT  200.419998  202.860001  197.509995  201.300003  201.300003  39799500

回答1:


This looks like a simple stacking operation. Let's go with

df = yf.download(tickers = ['AAPL', 'MSFT'], period = '2d') # get yer data
df.stack(level=1).rename_axis(['Date', 'symbol']).reset_index(level=1)

           symbol   Adj Close  ...        Open    Volume
Date                           ...                      
2020-07-23   AAPL  371.380005  ...  387.989990  49251100
2020-07-23   MSFT  202.539993  ...  207.190002  67457000
2020-07-24   AAPL  370.459991  ...  363.950012  46323800
2020-07-24   MSFT  201.300003  ...  200.419998  39799500

[4 rows x 7 columns]


来源:https://stackoverflow.com/questions/63106554/pandas-column-multi-index-to-rows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!