Pandas 基于现有列的相邻值向dataframe添加列

Pandas 基于现有列的相邻值向dataframe添加列,pandas,dataframe,Pandas,Dataframe,我有一个数据框df,有3列:time(时间戳)、id(str)和red(布尔值)。我想添加另一个布尔列,每行检查这一行或该id的任何按时间顺序排列的下两行是否为红色。(如果在这行之后有少于两行相同ID的话,我们只考虑我们所拥有的行) 这样做的优雅方式是什么我的方法并不优雅: 我按时间排序,创建了一个名为new\u col的空列表,并通过以下方式在df的所有行上循环填充它: (用于xrange(len(df)-2)中的行号)) 使用iloc,然后键入df['col']=new\u col。这很慢,

我有一个数据框
df
,有3列:
time
(时间戳)、
id
(str)和
red
(布尔值)。我想添加另一个布尔列,每行检查这一行或该id的任何按时间顺序排列的下两行是否为红色。(如果在这行之后有少于两行相同ID的话,我们只考虑我们所拥有的行) 这样做的优雅方式是什么我的方法并不优雅: 我按时间排序,创建了一个名为
new\u col
的空列表,并通过以下方式在
df
的所有行上循环填充它:

用于xrange(len(df)-2)中的行号)


使用
iloc
,然后键入
df['col']=new\u col
。这很慢,可读性不强。

假设您首先按时间戳排序,您可以按id分组,对于每个组,将
红色的值移位一次和两次,然后找到结果的逻辑or:

 df['col'] = df.red.groupby(df.id).apply(lambda g: g | g.shift(-1) | g.shift(-2))
例如:

In [100]: df = pd.DataFrame({'red': [True, True, True, False, False, True, True, True], 'id': [0] * 6 + [1] * 2})

In [101]: df.red.groupby(df.id).apply(lambda g: g | g.shift(-1) | g.shift(-2))
Out[101]: 
0    True
1    True
2    True
3    True
4    True
5    True
6    True
7    True
Name: red, dtype: bool

我同意Ami,但有一点需要注意,我相信您只想检查后续行中的红色/非红色,因此我将删除
groupby
中的第一个
语句:

# df1 (original df)
#   id    red        time
# 0  1   True  2016-09-01
# 1  1   True  2016-09-02
# 2  1   True  2016-09-03
# 3  2   True  2016-09-02
# 4  3  False  2016-09-03
# 5  4  False  2016-09-04
# 6  5  False  2016-09-05

df2 = df1.groupby(['id'])['red'].apply(lambda g: g.shift(-1) | g.shift(-2)).reset_index()
df2.drop(labels='index', axis=1, inplace=True)
df2.rename(columns={0: 'next red'}, inplace=True)
df1.join(other=df2)

输出:

  id    red        time next red
0  1   True  2016-09-01     True
1  1   True  2016-09-02     True
2  1   True  2016-09-03    False
3  2   True  2016-09-02    False
4  3  False  2016-09-03    False
5  4  False  2016-09-04    False
6  5  False  2016-09-05    False

我如何将问题的
id
部分合并进来?我对这个答案投了赞成票,因为在阅读了这个问题之后,我不确定你的解释是否正确。