根据另一列上的索引给定条件移动列的元素

时间:2017-01-13 21:14:43

标签: python pandas dataframe shift

我有一个包含2列和1个索引的数据帧(df)。

索引是日期时间索引,格式为2001-01-30 ....等,索引按DATE排序,有数千个相同的日期(并且是每月日期)。 A栏是公司名称(对应于日期),B栏是A栏中公司名称对于索引中日期的股价。

现在每个日期的A列都有多家公司,公司确实会随着时间而变化(因此数据无法完全预测)。

我想创建一个C列,它落后于B转发到下一个日期的所有价格(按照索引中的那样)。

基本的.shift()不起作用,因为我要求所有的价格根据公司在指数的下一个点仍然存在的条件进行转移。

我想要一个将B向前移动1的列C,以及一个将它向后移动1的列D.

我已经坚持了一段时间,有人非常聪明,请帮助。

由于

1 个答案:

答案 0 :(得分:1)

考虑下面的示例数据框df

np.random.seed([3,1415])
df = pd.concat(dict(
        A=pd.Series(np.random.rand(10), pd.date_range('2016-09-30', periods=10)),
        B=pd.Series(np.random.rand(7), pd.date_range('2016-09-25', periods=7)),
        C=pd.Series(np.random.rand(10), pd.date_range('2016-09-20', periods=10)),
        D=pd.Series(np.random.rand(8), pd.date_range('2016-10-30', periods=8)),
        E=pd.Series(np.random.rand(12), pd.date_range('2016-10-25', periods=12)),
        F=pd.Series(np.random.rand(14), pd.date_range('2016-08-30', periods=14)),

    )).rename_axis(['ColumnA', None]).reset_index('ColumnA', name='ColumnB')

print(df.head(10))

           ColumnA   ColumnB
2016-09-30       A  0.444939
2016-10-01       A  0.407554
2016-10-02       A  0.460148
2016-10-03       A  0.465239
2016-10-04       A  0.462691
2016-10-05       A  0.016545
2016-10-06       A  0.850445
2016-10-07       A  0.817744
2016-10-08       A  0.777962
2016-10-09       A  0.757983

使用groupby + shift

d1 = df.set_index('ColumnA', append=True)
g = d1.groupby(level='ColumnA').ColumnB
keys = ['Forward', 'Back']
new_df = d1.join(pd.concat([g.shift(i) for i in [-1, 1]], axis=1, keys=keys))
print(new_df.query('ColumnA == "A"').head(10))

                     ColumnB   Forward      Back
           ColumnA                              
2016-09-30 A        0.444939  0.407554       NaN
2016-10-01 A        0.407554  0.460148  0.444939
2016-10-02 A        0.460148  0.465239  0.407554
2016-10-03 A        0.465239  0.462691  0.460148
2016-10-04 A        0.462691  0.016545  0.465239
2016-10-05 A        0.016545  0.850445  0.462691
2016-10-06 A        0.850445  0.817744  0.016545
2016-10-07 A        0.817744  0.777962  0.850445
2016-10-08 A        0.777962  0.757983  0.817744
2016-10-09 A        0.757983       NaN  0.777962