例如,我有一个 pandas 数据框
df_dupl = pd.DataFrame({
'EVENT_TIME': ['00:01', '00:01', '00:01', '00:03', '00:03', '00:03', '00:06', '00:06', '00:06', '00:08', '00:08', '00:10', '00:10', '00:11', '00:11', '00:13', '00:13', '00:13'],
'UNIQUE_ID': [123, 123, 123, 125, 125, 125, 123, 123, 123, 127, 127, 123, 123, 123, 123, 123, 123, 123],
'Value1': ['A', 'B', 'A', 'A', 'B', 'A', 'A', 'B', 'A', 'A', 'B', 'A', 'B', 'C', 'B', 'A', 'B', 'A'],
'Value2': [0.3, 0.2, 0.2, 0.1, 1.3, 0.2, 0.3, 0.2, 0.2, 0.1, 1.3, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2, 0.2]
})
我想删除与具有相同 UNIQUE_ID 的先前(按 EVENT_TIME)行具有相同值的行序列。对于该示例,结果应如下所示:
df = pd.DataFrame({
'EVENT_TIME': ['00:01', '00:01', '00:01', '00:03', '00:03', '00:03', '00:08', '00:08', '00:10', '00:10', '00:11', '00:11', '00:13', '00:13', '00:13'],
'UNIQUE_ID': [123, 123, 123, 125, 125, 125, 127, 127, 123, 123, 123, 123, 123, 123, 123],
'Value1': ['A', 'B', 'A', 'A', 'B', 'A', 'A', 'B', 'A', 'B', 'C', 'B', 'A', 'B', 'A'],
'Value2': [0.3, 0.2, 0.2, 0.1, 1.3, 0.2, 0.1, 1.3, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2, 0.2]
}).
应删除时间为 00:06 的行,因为前一个具有 UNIQUE_ID 123(时间 00:01)的子数据帧是相同的。另一方面,时间为 00:13 的行应该保留 - 它们也与时间为 00:01 的行相同,但中间还有其他 UNIQUE_ID 123 的行。关键是我想比较整个子数据帧,而不是单行。
我可以通过使用以下函数达到预期的结果,但速度很慢。
def del_dupl_gr(df):
out = []
for x in df['UNIQUE_ID'].unique():
prev_df = pd.DataFrame()
for y in df[df['UNIQUE_ID'] == x]['EVENT_TIME'].unique():
test_df = df[(df['UNIQUE_ID'] == x) & (df['EVENT_TIME'] == y)]
if not test_df.iloc[:, 2:].reset_index(drop=True).equals(prev_df.iloc[:, 2:].reset_index(drop=True)):
out.append(test_df)
prev_df = test_df
return pd.concat(out).sort_index().reset_index(drop=True)
真实的数据帧非常大(超过百万行),并且这种循环需要很多时间。我确信必须有适当的(或至少更快)的方法来做到这一点。
结果
感谢您提交的所有答案。我比较了他们的速度。在某些情况下,我稍微编辑了方法以产生完全相同的结果。因此,在所有 sort_values 方法中,我添加了 kind='stable' 以确保保留顺序,最后我添加了 .reset_index(drop=True)。
方法 | 1000 行 | 10 000 行 | 100 000 行 |
---|---|---|---|
原来的 | 556 毫秒 | 5.41秒 | 未测试 |
莫兹韦 | 1.24秒 | 10.1秒 | 未测试 |
安德烈·凯斯利 | 696 毫秒 | 4.56秒 | 未测试 |
光黄 | 11.3 毫秒 | 34.1 毫秒 | 318 毫秒 |
另一种方法是通过枚举移动行,然后进行比较:
输出:
您可以形成组并散列子数据帧,然后
groupby.shift
与前一个块进行比较:输出:
中间体:
另一种方法:
印刷: