简体   繁体   中英

pandas: slicing multiindex data frames… simple series desired

I've created a multiindex of stock data by getting a panel from datareader and converting it to a multiindex dataframe. Sometimes when I use .loc I get a series with 1 index and sometimes I get a series with two indices. How can I slice by date and get a series with one index? Code will help...

import pandas_datareader.data as web

# Define the securities to download
symbols = ['AAPL', 'MSFT']

# Define which online source one should use
data_source = 'yahoo'

# Define the period of interest
start_date = '2010-01-01'
end_date = '2010-12-31'

# User pandas_reader.data.DataReader to load the desired data. 
panel = web.DataReader(symbols, data_source, start_date, end_date)

# Convert panel to multiindex dataframe
midf = panel.to_frame()

# for slicing multiindex dataframes it must be sorted
midf = midf.sort_index(level=0)

Here I select the column I want:

adj_close = midf['Adj Close']
adj_close.head()

I get a series with two indices ( Date and minor ):

Date        minor
2010-01-04  AAPL     27.505054
            SPY      96.833946
2010-01-05  AAPL     27.552608
            SPY      97.090271
2010-01-06  AAPL     27.114347
Name: Adj Close, dtype: float64

Now I select apple using : to select all dates.

aapl_adj_close = adj_close.loc[:, 'AAPL']
aapl_adj_close.head()

And get a series with the index Date . This is what I'm looking for!

Date
2010-01-04    27.505054
2010-01-05    27.552608
2010-01-06    27.114347
2010-01-07    27.064222
2010-01-08    27.244156
Name: Adj Close, dtype: float64

But when I actually slice by dates, I don't get that series:

sliced_aapl_adj_close  = adj_close.loc['2010-01-04':'2010-01-06', 'AAPL']
sliced_aapl_adj_close.head()

I get a series with two indices:

Date        minor
2010-01-04  AAPL     27.505054
2010-01-05  AAPL     27.552608
2010-01-06  AAPL     27.114347
Name: Adj Close, dtype: float64

The slice is right and the values are right but I don't want the minor index in there (as I want to pass this series to plot). What's the right way to slice this?

Thanks!

You can use:

df = df.reset_index(level=1, drop=True)

Or:

df.index = df.index.droplevel(1)

Another solution is reshape by unstack for DataFrame and then select by [] :

df = adj_close.unstack()

print (df)
minor            AAPL        SPY
Date                            
2010-01-04  27.505054  96.833946
2010-01-05  27.552608  97.090271
2010-01-06  27.114347        NaN

print (df['AAPL'])

Date
2010-01-04    27.505054
2010-01-05    27.552608
2010-01-06    27.114347
Name: AAPL, dtype: float64

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM