如何使用pandas将最后一行移至第一行?

9

所以我有一个看起来像这样的数据框:

                         #1                     #2
1980-01-01               11.6985                126.0
1980-01-02               43.6431                134.0
1980-01-03               54.9089                130.0
1980-01-04               63.1225                126.0
1980-01-05               72.4399                120.0

我想要做的是将第一列的第一行(11.6985)向下移动1行,然后将第一列的最后一行(72.4399)移动到第一行第一列,如下所示:
                         #1                     #2
1980-01-01               72.4399                126.0
1980-01-02               11.6985                134.0
1980-01-03               43.6431                130.0
1980-01-04               54.9089                126.0
1980-01-05               63.1225                120.0

我的想法是使用这些数据框来查找每个转移的R^2值,因此我需要使用所有数据,否则可能无法正常工作。我已经尝试使用 pandas.Dataframe.shift()

print(data)

#Output
1980-01-01               11.6985                126.0
1980-01-02               43.6431                134.0
1980-01-03               54.9089                130.0
1980-01-04               63.1225                126.0
1980-01-05               72.4399                120.0

print(data.shift(1,axis = 0))

1980-01-01                   NaN                  NaN
1980-01-02               11.6985                126.0
1980-01-03               43.6431                134.0
1980-01-04               54.9089                130.0
1980-01-05               63.1225                126.0

所以它只是将两列向下移动,并且去掉了最后一行数据,这不是我想要的结果。有什么建议吗?
4个回答

13

不确定性能如何,但你可以尝试使用numpy.roll

import numpy as np
print(df.apply(np.roll, shift=1))

#                 #1     #2
#1980-01-01  72.4399  120.0
#1980-01-02  11.6985  126.0
#1980-01-03  43.6431  134.0
#1980-01-04  54.9089  130.0
#1980-01-05  63.1225  126.0

只需将第 #1 列移动:


df['#1'] = np.roll(df['#1'], shift=1)

print(df)
#                 #1     #2
#1980-01-01  72.4399  126.0
#1980-01-02  11.6985  134.0
#1980-01-03  43.6431  130.0
#1980-01-04  54.9089  126.0
#1980-01-05  63.1225  120.0

这个方法非常有效!它可以同时移动两列,但我想我会将这两列分别放入不同的数据框中,然后将其中一列移动1位以与另一列进行比较。谢谢! - pythonweb
如果您只想滚动一列,例如 df['#1'] = np.roll(df['#1'], shift=1) - Psidom

6

我认为您无法使用shift完成此操作,但一种方法是使用iloc

In [11]: res = df.iloc[np.arange(-1, len(df)-1)]

In [12]: res
Out[12]:
                 #1     #2
1980-01-05  72.4399  120.0
1980-01-01  11.6985  126.0
1980-01-02  43.6431  134.0
1980-01-03  54.9089  130.0
1980-01-04  63.1225  126.0

In [13]: res.index = df.index

In [14]: res
Out[14]:
                 #1     #2
1980-01-01  72.4399  120.0
1980-01-02  11.6985  126.0
1980-01-03  43.6431  134.0
1980-01-04  54.9089  130.0
1980-01-05  63.1225  126.0

如果你想要这个新的列(只针对#1):
In [21]: df.iloc[np.arange(-1, len(df)-1), 0]
Out[21]:
1980-01-05    72.4399
1980-01-01    11.6985
1980-01-02    43.6431
1980-01-03    54.9089
1980-01-04    63.1225
Name: #1, dtype: float64

In [22]: df.iloc[np.arange(-1, len(df)-1), 0].values
Out[22]: array([ 72.4399,  11.6985,  43.6431,  54.9089,  63.1225])

In [23]: df["new#1"] = df.iloc[np.arange(-1, len(df)-1), 0].values

In [24]: df
Out[24]:
                 #1     #2    new#1
1980-01-01  11.6985  126.0  72.4399
1980-01-02  43.6431  134.0  11.6985
1980-01-03  54.9089  130.0  43.6431
1980-01-04  63.1225  126.0  54.9089
1980-01-05  72.4399  120.0  63.1225

我怀疑只需要进行一点小调整,就可以用同样的思路将其变成一行代码。 - Andy Hayden

2

我知道这是一个很老的问题,但这是我的解决方案,我认为它更加简洁:

df = df.reindex(np.roll(df.index, shift=1))

0
创建一个带有所需排序的新列,然后只需对行进行排序即可。
df['new_col'] = range(1, len(df)+1)
df['new_col'].loc[len(df)-1] = 0
df['new_col'].loc[0] = len(df)
df = df.reset_index()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接