首页 > 解决方案 > 熊猫如何根据后面的行过滤前面的行

问题描述

我有一个这样的数据框

Day,Minute,Second,Value
1,1,0,1
1,2,1,2
1,3,1,2
1,2,6,0
1,2,1,1
1,2,5,1
2,0,1,1
2,0,5,2

有时传感器记录不正确的值并再次添加但具有正确的值。例如,在这里我们应该删除第二行和第三行,因为它们被来自它们之前的时间戳的第四行覆盖。如何过滤掉那些不必要的“坏”行?例如,预期的输出应该是:

Day,Minute,Second,Value
1,1,0,1
1,2,1,1
1,2,5,1
2,0,1,1
2,0,5,2

这是迭代解决方案的伪代码(对不起,格式中没有缩进,这是我的第一篇文章)

for row in dataframe:
for previous_row in rows in dataframe before row:
if previous_row > row:
delete previous row

我认为应该有一个矢量化的解决方案,尤其是对于第二个循环。我也不想修改我正在迭代的内容,但我不确定除了复制数据框之外还有其他选择。

这是一些使用示例数据框的入门代码

import pandas as pd
data = [{'Day':1, 'Minute':1, 'Second':0, 'Value':1},
{'Day':1, 'Minute':2, 'Second':1, 'Value':2}, 
{'Day':1, 'Minute':2, 'Second':6, 'Value':2}, 
{'Day':1, 'Minute':3, 'Second':1, 'Value':0},
{'Day':1, 'Minute':2, 'Second':1, 'Value':1},
{'Day':1, 'Minute':2, 'Second':5, 'Value':1}, 
{'Day':2, 'Minute':0, 'Second':1, 'Value':1}, 
{'Day':2, 'Minute':0, 'Second':5, 'Value':2}]

df = pd.DataFrame(data)

标签: pythonpandas

解决方案


如果您有多行用于相同Day, Minute, Second但不同的组合Value,我假设您想要保留最后记录的值并丢弃所有以前的值,因为它们是“坏的”。

您可以简单地使用drop_duplicates

df.drop_duplicates(subset=['Day', 'Minute', 'Second'], keep='last')

更新 v2:

如果您需要保留['Minute', 'Second']每天的最后一组组合,请识别单调递增Minute的组(因为它是两者中较大的时间单位)并选择max值为Group_Idfor each的组['Day']

res = pd.DataFrame()
for _, g in df.groupby(['Day']):
    g['Group_Id'] = (g.Minute.diff() < 0).cumsum()
    res = pd.concat([res, g[g['Group_Id'] == max(g['Group_Id'].values)]])

输出:

Day Minute  Second  Value   Group_Id
1   2       1       1       1
1   2       5       1       1
2   0       1       1       0
2   0       5       2       0

推荐阅读