Python 如何相对于pandas中的另一行获取最后N行(向量解决方案)?

Python 如何相对于pandas中的另一行获取最后N行(向量解决方案)?,python,pandas,dataframe,Python,Pandas,Dataframe,我在另一个较长的问题中提出了这个问题,但我想我试图一次问太多的问题。因此,为了简单起见: 我有一个数据框,每次试验都会按一个键。我想添加一列,显示最后N行。因此,如果我的数据如下所示: trial sid key_pressed RT 1 S04 x 0.502242 2 S04 m 0.348620 3 S04 m 0.312491 4

我在另一个较长的问题中提出了这个问题,但我想我试图一次问太多的问题。因此,为了简单起见:

我有一个数据框,每次试验都会按一个键。我想添加一列,显示最后N行。因此,如果我的数据如下所示:

trial sid  key_pressed        RT  
1     S04            x  0.502242        
2     S04            m  0.348620      
3     S04            m  0.312491       
4     S04            x  0.342541      
5     S04            n  0.419384       
6     S04            n  0.348211      
7     S04            z  0.376369   
之后,它看起来是这样的(对于每个sid):

有没有矢量化的解决方案?我似乎不知道如何选择相对行。(对熊猫来说是新事物——还不太擅长这样思考)

更新:根据以下贡献者的建议,我最终做了以下工作:

df['shifted'] = pd.concat([df.groupby('sid')['key_pressed'].shift(2) + df.groupby('sid')['key_pressed'].shift(1) + df.groupby('sid')['key_pressed'].shift(0)])

例如,它创建了一个字符串
mxm
。哪一个更好。

哦-也许这是最好的解决方案。可以将数据“移位”一定量:

df['shifted'] = df.groupby('sid')['key_pressed'].shift(2)

然后我可以从这个移位的数据创建列表。

一种方法是使用
shift
向下移动相关列
n
行,然后连接条目(它们是字符串,因此我们可以使用
+
):


这将创建前三个条目的字符串,并用逗号和空格分隔(而不是列表)。如果可能的话,我会避免在数据帧中使用列表,因为事情可能会变得有点混乱。

您想如何处理这些列表?在序列/数据帧中存储列表通常不是很方便。不管怎样,这会让你接近的。您必须处理
nans
,然后您就完成了

In [6]: pd.concat([df.key_pressed.shift(i) for i in [0, 1, 2]], 1).apply(tuple, 1).map(list)
Out[6]: 
0    [x, nan, nan]
1      [m, x, nan]
2        [m, m, x]
3        [x, m, m]
4        [n, x, m]
5        [n, n, x]
6        [z, n, n]
dtype: object
请注意,我们必须先转换为一个元组,然后再转换为一个列表,以避免pandas自动将列表转换为一个系列。试试这个,你就会明白为什么它不起作用:

pd.concat([df.key_pressed.shift(i) for i in [0, 1, 2]], 1).apply(list, 1)

此解决方案避免了循环,但我不确定它是否真的算作“矢量化”,因为一旦您开始使用
apply()
我认为您开始失去矢量化所带来的任何性能优势:

key_table = pd.concat(
    [df.key_pressed.shift(2), df.key_pressed.shift(1), df.key_pressed], 
    axis=1
)
 df['last_3'] = key_table.apply(
    lambda row: ', '.join(str(k) for k in row),
    axis=1
)
输出:

   trial  sid key_pressed        RT       last_3
0      1  S04           x  0.502242  nan, nan, x
1      2  S04           m  0.348620    nan, x, m
2      3  S04           m  0.312491      x, m, m
3      4  S04           x  0.342541      m, m, x
4      5  S04           n  0.419384      m, x, n
5      6  S04           n  0.348211      x, n, n
6      7  S04           z  0.376369      n, n, z

谢谢-我喜欢轮班。是的,我同意最好不要列出清单。(虽然我现在才意识到这一点)谢谢-存储列表的好处。我会考虑到这一点,只创建字符串。我想做的是检查列表是否是另一列的一部分。既然你已经提出来了,不管怎样,弦乐就容易多了。基本上,我将检查
zn
是否是
mznxm
的一部分(因此,
True
)。但是
nz
应该产生
False
key_table = pd.concat(
    [df.key_pressed.shift(2), df.key_pressed.shift(1), df.key_pressed], 
    axis=1
)
 df['last_3'] = key_table.apply(
    lambda row: ', '.join(str(k) for k in row),
    axis=1
)
   trial  sid key_pressed        RT       last_3
0      1  S04           x  0.502242  nan, nan, x
1      2  S04           m  0.348620    nan, x, m
2      3  S04           m  0.312491      x, m, m
3      4  S04           x  0.342541      m, m, x
4      5  S04           n  0.419384      m, x, n
5      6  S04           n  0.348211      x, n, n
6      7  S04           z  0.376369      n, n, z