Python 基于多索引数据帧级别重新确定价格基准的最有吸引力的方法是什么?

Python 基于多索引数据帧级别重新确定价格基准的最有吸引力的方法是什么?,python,pandas,dataframe,multi-index,rebasing,Python,Pandas,Dataframe,Multi Index,Rebasing,我有一个多索引数据帧,如下所示: In[114]: cdm Out[114]: Last TD Date Ticker 1983-03-30 CLM83 29.40 44 CLN83 29.35 76 CLQ83 29.20 105 CLU83 28.95 139 CLV83 28.95 167

我有一个多索引数据帧,如下所示:

In[114]: cdm
Out[114]: 
                    Last   TD
Date       Ticker            
1983-03-30 CLM83   29.40   44
           CLN83   29.35   76
           CLQ83   29.20  105
           CLU83   28.95  139
           CLV83   28.95  167
           CLX83   28.90  197
           CLZ83   28.75  230
1983-03-31 CLM83   29.29   43
           CLN83   29.24   75
           CLQ83   29.05  104
           CLU83   28.85  138
           CLV83   28.75  166
           CLX83   28.70  196
           CLZ83   28.60  229
1983-04-04 CLM83   29.44   39
           CLN83   29.25   71
           CLQ83   29.10  100
           CLU83   29.05  134
           CLV83   28.95  162
           CLX83   28.95  192
           CLZ83   28.85  225
1983-04-05 CLM83   29.71   38
           CLN83   29.54   70
           CLQ83   29.35   99
           CLU83   29.20  133
           CLV83   29.10  161
           CLX83   29.00  191
           CLZ83   29.00  224
1983-04-06 CLM83   29.90   37
           CLN83   29.68   69
                 ...  ...
2016-07-05 CLV6    47.91   72
           CLX6    48.51  104
           CLZ6    49.07  134
           CLF7    49.54  163
           CLG7    49.93  196
           CLH7    50.26  226
           CLJ7    50.53  254
           CLK7    50.77  286
           CLM7    51.00  316
           CLN7    51.20  345
           CLQ7    51.39  377
           CLU7    51.58  408
           CLV7    51.79  437
           CLX7    52.03  469
2016-07-06 CLQ6    47.43    9
           CLU6    48.14   42
           CLV6    48.75   71
           CLX6    49.34  103
           CLZ6    49.89  133
           CLF7    50.36  162
           CLG7    50.75  195
           CLH7    51.08  225
           CLJ7    51.35  253
           CLK7    51.60  285
           CLM7    51.84  315
           CLN7    52.05  344
           CLQ7    52.25  376
           CLU7    52.46  407
           CLV7    52.69  436
           CLX7    52.94  468

[289527 rows x 2 columns]
它相当大,我想重新确定价格,这意味着在每个时间点(每个“日期”)第一个价格(“最后一个”)被设置为100,其他价格则根据第一个价格进行衡量

我有以下功能:

def rebase(prices):
    return prices/prices[0]*100
为了实现我的目标,我还提出了一个小组。然而它却长得可笑:

%time cdm.groupby(level='Date')['Last'].apply(rebase)
Wall time: 1min 49s
Out[115]: 
Date        Ticker
1983-03-30  CLM83     100.000000
            CLN83      99.829932
            CLQ83      99.319728
            CLU83      98.469388
            CLV83      98.469388
            CLX83      98.299320
            CLZ83      97.789116
1983-03-31  CLM83     100.000000
            CLN83      99.829293
            CLQ83      99.180608
            CLU83      98.497781
            CLV83      98.156367
            CLX83      97.985661
            CLZ83      97.644247
1983-04-04  CLM83     100.000000
            CLN83      99.354620
            CLQ83      98.845109
            CLU83      98.675272
            CLV83      98.335598
            CLX83      98.335598
            CLZ83      97.995924
1983-04-05  CLM83     100.000000
            CLN83      99.427802
            CLQ83      98.788287
            CLU83      98.283406
            CLV83      97.946819
            CLX83      97.610232
            CLZ83      97.610232
1983-04-06  CLM83     100.000000
            CLN83      99.264214

2016-07-05  CLV6      102.811159
            CLX6      104.098712
            CLZ6      105.300429
            CLF7      106.309013
            CLG7      107.145923
            CLH7      107.854077
            CLJ7      108.433476
            CLK7      108.948498
            CLM7      109.442060
            CLN7      109.871245
            CLQ7      110.278970
            CLU7      110.686695
            CLV7      111.137339
            CLX7      111.652361
2016-07-06  CLQ6      100.000000
            CLU6      101.496943
            CLV6      102.783049
            CLX6      104.026987
            CLZ6      105.186591
            CLF7      106.177525
            CLG7      106.999789
            CLH7      107.695551
            CLJ7      108.264811
            CLK7      108.791904
            CLM7      109.297913
            CLN7      109.740670
            CLQ7      110.162345
            CLU7      110.605102
            CLV7      111.090027
            CLX7      111.617120
Name: Last, dtype: float64
完成这项工作需要1.30到3分钟的时间,我还需要进行更多的操作才能达到我想要的目的,即在我的第一个数据帧cdm中包含这列重新调整的价格:

groupRebP = cdm.groupby(level='Date')['Last'].apply(rebase)
groupRebP  = pd.DataFrame(groupRebP)
cdm['RebP'] = groupRebP['Last']
有没有一种更快、更像蟒蛇的方法来实现这一点

感谢您的提示,

设置 解决方案 经常使用
numpy

cdm_last = cdm.Last.unstack()
a = cdm_last.values

a_rebased = np.concatenate([np.ones((1, a.shape[1])),
                            np.exp(np.diff(np.log(a), axis=0))]) * 100

cdm_last_rebased = pd.DataFrame(a_rebased, cdm_last.index, cdm_last.columns)
cdm_last_rebased

堆叠
以取回您的序列

cdm_last_rebased.stack()

Date        Ticker
1983-03-30  CLM83     100.000000
            CLN83     100.000000
            CLQ83     100.000000
            CLU83     100.000000
            CLV83     100.000000
            CLX83     100.000000
            CLZ83     100.000000
1983-03-31  CLM83      99.625850
            CLN83      99.625213
            CLQ83      99.486301
            CLU83      99.654577
            CLV83      99.309154
            CLX83      99.307958
            CLZ83      99.478261
1983-04-04  CLM83     100.512120
            CLN83     100.034200
            CLQ83     100.172117
            CLU83     100.693241
            CLV83     100.695652
            CLX83     100.871080
            CLZ83     100.874126
1983-04-05  CLM83     100.917120
            CLN83     100.991453
            CLQ83     100.859107
            CLU83     100.516351
            CLV83     100.518135
            CLX83     100.172712
            CLZ83     100.519931
dtype: float64

谢谢你的回答。但是有一个问题。我还不明白你是怎么做的,但仅仅从你的结果来看,似乎价格并没有相对于网站上的第一个价格重新调整day@MthClv我忘了提这个了。我按“股票代码”而不是“日期”分组。我以为这是你的错别字,所以我做了调整。如果您确实希望以另一种方式完成:开始时使用
cdm\u last=cdm.last.unstack(0)
,最后使用
cdm\u last\u rebase.unstack()
。太好了,谢谢!我唯一想到的是,这种方法能否处理数据中不可避免的NAN?我的意思是它会忽视他们吗?我现在明白你所做的了。问题是在第一行插入一个,然后计算其他行的比率。但并非所有的股票在第一天就有价格。如果我换一种方式,所有日期也不会记录第一个股票的价格。因此,我需要一些能够处理的东西,您的样本不够大,无法看到问题的出现,但我的矩阵一旦堆叠,就会形成(8358414),有很多NAN。未缺失的价格位于主对角线上(从左上到右下)
cdm_last_rebased.stack()

Date        Ticker
1983-03-30  CLM83     100.000000
            CLN83     100.000000
            CLQ83     100.000000
            CLU83     100.000000
            CLV83     100.000000
            CLX83     100.000000
            CLZ83     100.000000
1983-03-31  CLM83      99.625850
            CLN83      99.625213
            CLQ83      99.486301
            CLU83      99.654577
            CLV83      99.309154
            CLX83      99.307958
            CLZ83      99.478261
1983-04-04  CLM83     100.512120
            CLN83     100.034200
            CLQ83     100.172117
            CLU83     100.693241
            CLV83     100.695652
            CLX83     100.871080
            CLZ83     100.874126
1983-04-05  CLM83     100.917120
            CLN83     100.991453
            CLQ83     100.859107
            CLU83     100.516351
            CLV83     100.518135
            CLX83     100.172712
            CLZ83     100.519931
dtype: float64