Problem with MultiIndex upsampling / resampling
#### Summary

Thanks for making Pandas I have used it in a lot of projects! But now I have a problem.

I have spent nearly 3 days trying to figure out how to **resample / upsample a Pandas MultiIndex** elegantly and correctly. I have read and tried numerous posts on StackOverflow and GitHub. My conclusion is that **I don't think this is supported very well in Pandas**. Let me explain what I want to do.

#### Background

I am currently building a Python API in collaboration with www.simfin.com that makes it very easy to download and use financial data (share-prices, fundamentals, etc.) for free. This will enable people to conduct and share financial research very easily. It works by downloading bulk-data in CSV files from the SimFin server and loading them in Pandas. The fundamental data such as Income Statements and Balance Sheets is usually indexed by the Ticker and Report Date which creates a Pandas DataFrame with a MultiIndex.

#### Data Example

Let us say we have a Pandas DataFrame `df` with this data:

                             Revenue  Net Income (Common)
    Ticker Report Date                                   
    AAPL   2007-09-30    24578000000           3495000000
           2008-09-30    37491000000           6119000000
           2009-09-30    42905000000           8235000000
           2010-09-30    65225000000          14013000000
           2011-09-30   108249000000          25922000000
           2012-09-30   156508000000          41733000000
           2013-09-30   170910000000          37037000000
           2014-09-30   182795000000          39510000000
           2015-09-30   233715000000          53394000000
           2016-09-30   215639000000          45687000000
           2017-09-30   229234000000          48351000000
           2018-09-30   265595000000          59531000000
    AMZN   2007-12-31    14835000000            476000000
           2008-12-31    19166000000            645000000
           2009-12-31    24509000000            902000000
           2010-12-31    34204000000           1152000000
           2011-12-31    48077000000            631000000
           2012-12-31    61093000000            -39000000
           2013-12-31    74452000000            274000000
           2014-12-31    88988000000           -241000000
           2015-12-31   107006000000            596000000
           2016-12-31   135987000000           2371000000
           2017-12-31   177866000000           3033000000
           2018-12-31   232887000000          10073000000
    MSFT   2008-06-30    60420000000          17681000000
           2009-06-30    58437000000          14569000000
           2010-06-30    62484000000          18760000000
           2011-06-30    69943000000          23150000000
           2012-06-30    73723000000          16978000000
           2013-06-30    77849000000          21863000000
           2014-06-30    86833000000          22074000000
           2015-06-30    93580000000          12193000000
           2016-06-30    91154000000          20539000000
           2017-06-30    96571000000          25489000000
           2018-06-30   110360000000          16571000000

#### Resample a single Ticker (DatetimeIndex)

Let us first resample for a single ticker:

    df.loc['MSFT'].resample('D').pad()

This works and the result is:

                     Revenue  Net Income (Common)
    Report Date                                  
    2008-06-30   60420000000          17681000000
    2008-07-01   60420000000          17681000000
    2008-07-02   60420000000          17681000000
    2008-07-03   60420000000          17681000000
    2008-07-04   60420000000          17681000000

#### Resample multiple Tickers (MultiIndex)

Let us now try and resample for all tickers in the DataFrame. The `resample()` function takes an argument `level` which is supposed to work with a MultiIndex DataFrame:

    df.resample('D', level='Report Date').pad()

But this apparently doesn't work for upsampling e.g. annual data to daily data, because we get this error message:

    ValueError: Upsampling from level= or on= selection is not supported, use .set_index(...) to explicitly set index to datetime-like

One solution is to use `groupby()` (adapted from e.g. #13699):

    df.reset_index('Ticker').groupby('Ticker').resample('D').pad()

This works, but it now has duplicated the Ticker both as an index and as a column:

                       Ticker      Revenue  Net Income (Common)
    Ticker Report Date                                         
    AAPL   2007-09-30    AAPL  24578000000           3495000000
           2007-10-01    AAPL  24578000000           3495000000
           2007-10-02    AAPL  24578000000           3495000000
           2007-10-03    AAPL  24578000000           3495000000
           2007-10-04    AAPL  24578000000           3495000000

We can avoid one of them by adding the arg `group_keys=False`:

    df.reset_index('Ticker').groupby('Ticker', group_keys=False).resample('D').pad()

This works, but now the Ticker is a data-column instead of an index:

                Ticker      Revenue  Net Income (Common)
    Report Date                                         
    2007-09-30    AAPL  24578000000           3495000000
    2007-10-01    AAPL  24578000000           3495000000
    2007-10-02    AAPL  24578000000           3495000000
    2007-10-03    AAPL  24578000000           3495000000
    2007-10-04    AAPL  24578000000           3495000000

To get the original MultiIndex back with both Ticker and Report Date, we need to do:

    df.reset_index('Ticker').groupby('Ticker', group_keys=False).resample('D').pad().reset_index().set_index(['Ticker', 'Report Date'])

Which produces the desired result:

                            Revenue  Net Income (Common)
    Ticker Report Date                                  
    AAPL   2007-09-30   24578000000           3495000000
           2007-10-01   24578000000           3495000000
           2007-10-02   24578000000           3495000000
           2007-10-03   24578000000           3495000000
           2007-10-04   24578000000           3495000000

But this is so complicated that nobody can be expected to remember how to do it. So I would have to make a small helper-function that does all of this. But because the resampling method (pad, interpolate, etc.) is invoked through a function call on the groupby-object, my helper-function would get big and awkward if I want to allow different methods of resampling.

#### Conclusion

It appears that upsampling a MultiIndex is not supported very well in Pandas, unless I have misunderstood how it is supposed to work.

I think that by far the most elegant solution would be if the `resample()` function supported the `level` argument for upsampling, because the syntax and semantics would be very similar for upsampling DatetimeIndex and MultiIndex:

    # DatetimeIndex
    df.loc['MSFT'].resample('D').pad()

    # MultiIndex
    df.resample('D', level='Report Date').pad()

I have taken a look at the Pandas source-code, but it is complicated and so sparsely documented, that it would take me forever to figure out how everything is connected and how it works, so I don't think I will be able to fix this myself. Is this something you could fix, because it would make it so much easier to upsample DataFrames with a MultiIndex?

Thanks!

<details>

INSTALLED VERSIONS
------------------
commit           : None
python           : 3.6.8.final.0
python-bits      : 64
OS               : Linux
OS-release       : 4.15.0-60-generic
machine          : x86_64
processor        : x86_64
byteorder        : little
LC_ALL           : None
LANG             : en_US.UTF-8
LOCALE           : en_US.UTF-8

pandas           : 0.25.1
numpy            : 1.16.4
pytz             : 2019.2
dateutil         : 2.8.0
pip              : 19.1.1
setuptools       : 41.0.1
Cython           : None
pytest           : None
hypothesis       : None
sphinx           : None
blosc            : None
feather          : None
xlsxwriter       : None
lxml.etree       : None
html5lib         : None
pymysql          : None
psycopg2         : None
jinja2           : 2.10.1
IPython          : 7.5.0
pandas_datareader: None
bs4              : None
bottleneck       : None
fastparquet      : None
gcsfs            : None
lxml.etree       : None
matplotlib       : 3.1.0
numexpr          : None
odfpy            : None
openpyxl         : None
pandas_gbq       : None
pyarrow          : None
pytables         : None
s3fs             : None
scipy            : 1.3.1
sqlalchemy       : None
tables           : None
xarray           : None
xlrd             : None
xlwt             : None
xlsxwriter       : None

</details>