Python 如何相对于pandas中的另一行获取最后N行(向量解决方案)?
我在另一个较长的问题中提出了这个问题,但我想我试图一次问太多的问题。因此,为了简单起见: 我有一个数据框,每次试验都会按一个键。我想添加一列,显示最后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
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