Pandas 将价格序列“指数化”到一个起始时间点(指数水平=100),数据帧为:P(i,t)/P(i)

Pandas 将价格序列“指数化”到一个起始时间点(指数水平=100),数据帧为:P(i,t)/P(i),pandas,dataframe,arithmetic-expressions,scalar,Pandas,Dataframe,Arithmetic Expressions,Scalar,我有一个pandas数据框,其中datetime是数据框的索引,我使用t=0进行简化,实际上有类似20170101 09:30:00的内容 datetime Stock A Stock B t=0 5 20 t=1 6 30 t=2 8 25 t=3 4 20 我想返回: datetime Stock A Stock B

我有一个pandas数据框,其中datetime是数据框的索引,我使用t=0进行简化,实际上有类似20170101 09:30:00的内容

datetime    Stock A    Stock B
t=0           5          20
t=1           6          30
t=2           8          25
t=3           4          20
我想返回:

datetime    Stock A    Stock B
t=0           100        100
t=1           120        150
t=2           140        125
t=3           80         100
用数学术语:Indexi,t=Pi,t/Pi,0

我试过了

df_norm =  df[0:] / df[0:1]
print(df_norm)
这给了我一个错误

edit1:我尝试了工作正常的选项3,但还不能尝试NaN,但至少它没有为pctchange导致的第一个obs创建NaN。我还想知道,在执行之后,我的datetime不再是集合索引,这很容易通过重新分配它来修复

现在我尝试将其包装到函数中,但我认为索引导致的问题实际上与我第一次尝试时的错误相同:

def norming(x):
    return x.assign(**x.drop('datetime', 1).pipe(
    lambda d: d.div(d.shift().bfill()).cumprod()))
edit2:如果我的列datetime是一个索引,即

df_norm.set_index(['datetime'], inplace = True)
但是,我会得到一个错误,我需要更改什么?

选项1 选择2 选择3 好像

p=100/df.iloc[0,1:]
df.iloc[:,1:]*=p
df
Out[1413]: 
  datetime StockA StockB
0      t=0    100    100
1      t=1    120    150
2      t=2    160    125
3      t=3     80    100

比我的答案好得多@piRSquared更好,因为他也得到了回报率:-我的df.assign版本**df.drop'datetime',1.pipelambda d:d.divd.iloc[0]。mul100@piRSquared这太棒了,先生:-谢谢你们的回答!在选项1中,我看到了fillna,我的数据中不时会出现NaN,实际上我希望保留它。这也会影响其他解决方案吗?此外,如果不太费劲,您是否介意对代码进行评论?代码中有一些特定的部分和语法我并不真正理解。复活节快乐!
def idx_me(a):
    a = np.asarray(a)
    r = np.append(1, a[1:] / a[:-1])
    return r.cumprod() * 100

df.assign(**df.drop('datetime', 1).apply(idx_me))

  datetime  Stock A  Stock B
0      t=0    100.0    100.0
1      t=1    120.0    150.0
2      t=2    160.0    125.0
3      t=3     80.0    100.0
df.assign(**df.drop('datetime', 1).pipe(
    lambda d: d.div(d.shift().bfill()).cumprod().mul(100)))

  datetime  Stock A  Stock B
0      t=0    100.0    100.0
1      t=1    120.0    150.0
2      t=2    160.0    125.0
3      t=3     80.0    100.0
p=100/df.iloc[0,1:]
df.iloc[:,1:]*=p
df
Out[1413]: 
  datetime StockA StockB
0      t=0    100    100
1      t=1    120    150
2      t=2    160    125
3      t=3     80    100