MultiIndexed Dataframes的Pandas设计注意事项

时间:2016-07-13 13:11:16

标签: python pandas

这个问题的目的是进一步探讨MultiIndex dataframes,并就各种任务提出最佳方法的问题。

创建DataFrame

import pandas as pd

df = pd.DataFrame({'index_date' : ['12/07/2016','12/07/2016','12/07/2016','12/07/2016','12/07/2016'], 
               'portfolio' : ['A','B','C','D','E'], 
               'reporting_ccy' : ['GBP','GBP','GBP','GBP','GBP'],
               'portfolio_ccy' : ['JPY','USD','USD','EUR','EUR'],
               'amount' : [100,200,300,400,500],
               'injection' : [1,2,3,4,5],
               'to_usd' : [1.3167,1.3167,1.3167,1.3167,1.3167],
               'to_ccy' : [0.009564,1,1,1.1093,1.1093],
               'm5' : [2,4,6,8,10],
               'm6' : [1,3,5,7,9]}); 

透视数据框

df_pivot = df.pivot_table(index='index_date',columns=['portfolio','portfolio_ccy','reporting_ccy']).swaplevel(0, 1, axis=1).sortlevel(axis=1)

重命名列

df_pivot.columns.names = ['portfolio','measures', 'portfolio_ccy', 'reporting_ccy']

这产生了数据的旋转表示,以便:

  1. 投资组合可能有一个或多个措施
  2. 显示投资组合默认货币
  3. 显示投资组合报告货币
  4. 度量可能包含1种或多种报告货币。
  5. 我的条款4.鉴于我们有货币的xRates,实施的最佳方法是什么?

    这样我们就可以创建一个数据框,例如派生的数据框:

    创建DataFrame

    df1 = pd.DataFrame({'index_date' : ['12/07/2016','12/07/2016','12/07/2016','12/07/2016','12/07/2016'], 
               'portfolio' : ['A','B','C','D','E'], 
               'reporting_ccy' : ['JPY','USD','USD','EUR','EUR'],
               'portfolio_ccy' : ['JPY','USD','USD','EUR','EUR'],
               'amount' : [13767.2522, 263.34, 395.01, 474.785901, 593.4823763],
               'injection' : [1,2,3,4,5],
               'to_usd' : [0.009564, 1, 1, 1.1093, 1.1093],
               'to_ccy' : [1.3167, 1.3167, 1.3167, 1.3167, 1.3167],
               'm5' : [2,4,6,8,10],
               'm6' : [1,3,5,7,9]}); 
    

    连接&透视数据框

    df_concat = pd.concat([df,df1])
    df_pivot1 = df_concat.pivot_table(index='index_date',columns=['portfolio','portfolio_ccy','reporting_ccy']).swaplevel(0, 1, axis=1).sortlevel(axis=1)
    df_pivot1.columns.names = ['portfolio','measures', 'portfolio_ccy', 'reporting_ccy']
    

    现在显示1种具有多种货币的指标。

    df_pivot1.xs(('amount', 'A'), level=('measures','portfolio'), drop_level=False, axis=1)
    

    问题

    是否有更好的方法,例如将数据直接添加到3级df_pivot1.columns.get_level_values(3).unique()的多索引数据框?

    我希望能够遍历每个级别并添加使用df.assign()或其他方法从其他度量派生的新度量。

    此处的用例是在适用的措施中添加其他货币。如上所述的连接和重新调整似乎不是最佳的。

2 个答案:

答案 0 :(得分:2)

你可以逐行将df1追加到df_pivot上,而不是重建枢轴,两个帧连在一起。

每次收到新数据时,追加到DataFrame的末尾所需的内存比连接和重建枢轴的内存要便宜。

import pandas as pd

df = pd.DataFrame({'index_date' : ['12/07/2016','12/07/2016','12/07/2016','12/07/2016','12/07/2016'], 
               'portfolio' : ['A','B','C','D','E'], 
               'reporting_ccy' : ['GBP','GBP','GBP','GBP','GBP'],
               'portfolio_ccy' : ['JPY','USD','USD','EUR','EUR'],
               'amount' : [100,200,300,400,500],
               'injection' : [1,2,3,4,5],
               'to_usd' : [1.3167,1.3167,1.3167,1.3167,1.3167],
               'to_ccy' : [0.009564,1,1,1.1093,1.1093],
               'm5' : [2,4,6,8,10],
               'm6' : [1,3,5,7,9]}); 

# %%
df_pivot = df.pivot_table(index='index_date',columns=['portfolio','portfolio_ccy','reporting_ccy']).swaplevel(0, 1, axis=1).sortlevel(axis=1)
df1 = pd.DataFrame({'index_date' : ['12/07/2016','12/07/2016','12/07/2016','12/07/2016','12/07/2016'], 
           'portfolio' : ['A','B','C','D','E'], 
           'reporting_ccy' : ['JPY','USD','USD','EUR','EUR'],
           'portfolio_ccy' : ['JPY','USD','USD','EUR','EUR'],
           'amount' : [13767.2522, 263.34, 395.01, 474.785901, 593.4823763],
           'injection' : [1,2,3,4,5],
           'to_usd' : [0.009564, 1, 1, 1.1093, 1.1093],
           'to_ccy' : [1.3167, 1.3167, 1.3167, 1.3167, 1.3167],
           'm5' : [2,4,6,8,10],
           'm6' : [1,3,5,7,9]}); 

df_pivot.columns.names = ['portfolio','measures', 'portfolio_ccy', 'reporting_ccy']
# instead of joining the 2 df's add df1 to df_pivot 1 row at a time. 
for i in range(len(df1)):
    row = df1.iloc[i]
    for measure in 'amount injection m5 m6 to_ccy to_usd'.split():
        df_pivot.ix[row.index_date, (row.portfolio,measure,row.portfolio_ccy, row.reporting_ccy)] = row[measure]

#%% check the end result
print(df_pivot.xs(('amount', 'A'), 
      level=('measures','portfolio'), drop_level=False, axis=1))   

答案 1 :(得分:2)

我对信息过载感到非常困惑 但是,如果我理解正确的话:

  

我所暗示的是,在多指数数据框中添加较低级别并不容易。

考虑df

df = pd.DataFrame(np.arange(64).reshape(-1, 8), list('abcdefgh'), list('ABCDEFGH'))
df

enter image description here

我们可以轻松地将一个级别添加到索引的内部级别

df.index = [df.index, list('XY') * 4]
df

enter image description here