Pandas - groupby 如果满足条件
Pandas - groupby if Criteria Met
以下数据基于面包车的 GPS 坐标、点火是否 on/off 以及面包车在给定时间与目标位置的距离。我想确定面包车是否在某个位置(<300)或附近,点火开关是否已关闭,如果两个条件都为真,则停留时间。
在下面的示例中,我将第 1-4 行可视化为 "grouped" 在一起,因为它们是距离 <300 的连续行。第 5 行单独 "grouped",因为它 >300,第 6-8 行在一起 "grouped",因为它们是距离 <300.
的连续行
因此,由于第 1-4 行的点火开关已关闭,我想计算持续时间(自货车 "stopped" 在该位置停留给定的时间)。但是,其他两组(第 5 行和第 6-8 行)不应计算持续时间,因为在这些组中从未关闭点火装置。
df
AcctID On_Off Distance Timestamp
123 On 230 12:00
123 On 30 12:02
123 Off 29 12:05
123 Off 35 12:10
123 On 3000 12:13
123 On 100 12:20
123 On 95 12:22
123 On 240 12:28
我能够对距离是否小于 300 (Within_Distance
) 进行分类,但是确定分组中至少一排的点火装置是否关闭让我感到困惑。这是最终数据框的样子:
df['Within_Distance'] = np.where(df['Distance']<300, "Yes", "No")
df
AcctID On_Off Distance Timestamp Within_Distance Was_Off Within_Distance_and_Was_Off
123 On 230 12:20 Yes Yes Yes
123 On 30 12:02 Yes Yes Yes
123 Off 29 12:05 Yes Yes Yes
123 Off 35 12:10 Yes Yes Yes
123 On 3000 12:13 No No No
123 On 100 12:20 Yes No No
123 On 95 12:22 Yes No No
123 On 240 12:28 Yes No No
提前致谢!
让我们试试:
df['Within_Distance'] = np.where(df['Distance']<300, "Yes", "No")
df['Was_Off'] = df.groupby((df.Distance > 300).diff().fillna(0).cumsum())['On_Off'].transform(lambda x: 'Yes' if (x == 'Off').any() else 'No')
df['Within_Distinace_and_Was_Off'] = np.where((df['Within_Distance'] == 'Yes') & (df['Was_Off'] == 'Yes'),'Yes','No')
输出:
AcctID On_Off Distance Timestamp Within_Distance Was_Off \
0 123 On 230 12:00 Yes Yes
1 123 On 30 12:02 Yes Yes
2 123 Off 29 12:05 Yes Yes
3 123 Off 35 12:10 Yes Yes
4 123 On 3000 12:13 No No
5 123 On 100 12:20 Yes No
6 123 On 95 12:22 Yes No
7 123 On 240 12:28 Yes No
Within_Distinace_and_Was_Off
0 Yes
1 Yes
2 Yes
3 Yes
4 No
5 No
6 No
7 No
首先,设置一个布尔字段以使用
df['Off'] = df['On_Off'] == 'Off'
然后构造一个标识groupby
连续行的字段,如图
(df['Within_Distance'] != df['Within_Distance'].shift()).cumsum()
并使用 .any
确定 groupby 中任何行的布尔值在哪里为真:
df['Was_Off'] = df.groupby((df['Within_Distance'] != df['Within_Distance'].shift()).cumsum())['Off'].transform(any)
Out[31]:
AcctID On_Off Distance Timestamp Within_Distance Off Was_Off
0 123 On 230 12:00 Yes False True
1 123 On 30 12:02 Yes False True
2 123 Off 29 12:05 Yes True True
3 123 Off 35 12:10 Yes True True
4 123 On 3000 12:13 No False False
5 123 On 100 12:20 Yes False False
6 123 On 95 12:22 Yes False False
7 123 On 240 12:28 Yes False False
以下数据基于面包车的 GPS 坐标、点火是否 on/off 以及面包车在给定时间与目标位置的距离。我想确定面包车是否在某个位置(<300)或附近,点火开关是否已关闭,如果两个条件都为真,则停留时间。
在下面的示例中,我将第 1-4 行可视化为 "grouped" 在一起,因为它们是距离 <300 的连续行。第 5 行单独 "grouped",因为它 >300,第 6-8 行在一起 "grouped",因为它们是距离 <300.
的连续行因此,由于第 1-4 行的点火开关已关闭,我想计算持续时间(自货车 "stopped" 在该位置停留给定的时间)。但是,其他两组(第 5 行和第 6-8 行)不应计算持续时间,因为在这些组中从未关闭点火装置。
df
AcctID On_Off Distance Timestamp
123 On 230 12:00
123 On 30 12:02
123 Off 29 12:05
123 Off 35 12:10
123 On 3000 12:13
123 On 100 12:20
123 On 95 12:22
123 On 240 12:28
我能够对距离是否小于 300 (Within_Distance
) 进行分类,但是确定分组中至少一排的点火装置是否关闭让我感到困惑。这是最终数据框的样子:
df['Within_Distance'] = np.where(df['Distance']<300, "Yes", "No")
df
AcctID On_Off Distance Timestamp Within_Distance Was_Off Within_Distance_and_Was_Off
123 On 230 12:20 Yes Yes Yes
123 On 30 12:02 Yes Yes Yes
123 Off 29 12:05 Yes Yes Yes
123 Off 35 12:10 Yes Yes Yes
123 On 3000 12:13 No No No
123 On 100 12:20 Yes No No
123 On 95 12:22 Yes No No
123 On 240 12:28 Yes No No
提前致谢!
让我们试试:
df['Within_Distance'] = np.where(df['Distance']<300, "Yes", "No")
df['Was_Off'] = df.groupby((df.Distance > 300).diff().fillna(0).cumsum())['On_Off'].transform(lambda x: 'Yes' if (x == 'Off').any() else 'No')
df['Within_Distinace_and_Was_Off'] = np.where((df['Within_Distance'] == 'Yes') & (df['Was_Off'] == 'Yes'),'Yes','No')
输出:
AcctID On_Off Distance Timestamp Within_Distance Was_Off \
0 123 On 230 12:00 Yes Yes
1 123 On 30 12:02 Yes Yes
2 123 Off 29 12:05 Yes Yes
3 123 Off 35 12:10 Yes Yes
4 123 On 3000 12:13 No No
5 123 On 100 12:20 Yes No
6 123 On 95 12:22 Yes No
7 123 On 240 12:28 Yes No
Within_Distinace_and_Was_Off
0 Yes
1 Yes
2 Yes
3 Yes
4 No
5 No
6 No
7 No
首先,设置一个布尔字段以使用
df['Off'] = df['On_Off'] == 'Off'
然后构造一个标识groupby
连续行的字段,如图
(df['Within_Distance'] != df['Within_Distance'].shift()).cumsum()
并使用 .any
确定 groupby 中任何行的布尔值在哪里为真:
df['Was_Off'] = df.groupby((df['Within_Distance'] != df['Within_Distance'].shift()).cumsum())['Off'].transform(any)
Out[31]:
AcctID On_Off Distance Timestamp Within_Distance Off Was_Off
0 123 On 230 12:00 Yes False True
1 123 On 30 12:02 Yes False True
2 123 Off 29 12:05 Yes True True
3 123 Off 35 12:10 Yes True True
4 123 On 3000 12:13 No False False
5 123 On 100 12:20 Yes False False
6 123 On 95 12:22 Yes False False
7 123 On 240 12:28 Yes False False