Pandas 删除组的连续重复项

Pandas 删除组的连续重复项,pandas,numpy,Pandas,Numpy,我正在删除数据帧中成组的连续重复项。我正在寻找一种比这更快的方法: def remove_consecutive_dupes(subdf): dupe_ids = [ "A", "B" ] is_duped = (subdf[dupe_ids].shift(-1) == subdf[dupe_ids]).all(axis=1) subdf = subdf[~is_duped] return subdf # datafram

我正在删除数据帧中成组的连续重复项。我正在寻找一种比这更快的方法:

def remove_consecutive_dupes(subdf):
    dupe_ids = [ "A", "B" ]
    is_duped = (subdf[dupe_ids].shift(-1) == subdf[dupe_ids]).all(axis=1)
    subdf = subdf[~is_duped]
    return subdf

# dataframe with columns key, A, B
df.groupby("key").apply(remove_consecutive_dupes).reset_index()
是否可以在不进行分组的情况下删除这些内容?将上述函数单独应用于每个组需要花费大量时间,尤其是当组计数大约为行计数的一半时。有没有一种方法可以同时对整个数据帧执行此操作

如果上述内容不清楚,则为算法提供一个简单示例:

输入:

  key  A  B
0   x  1  2
1   y  1  4
2   x  1  2
3   x  1  4
4   y  2  5
5   x  1  2
输出:

  key  A  B
0   x  1  2
1   y  1  4
3   x  1  4
4   y  2  5
5   x  1  2
第2行被删除,因为
A=1 B=2
也是组
x
中的前一行。
第5行不会被删除,因为它在组
x

中不是一个连续的重复项。根据您的代码,只有在下列情况下,行才会显示在彼此下方 它们按键分组。因此,中间有另一个键的行不会影响此逻辑。但这样做,您希望保留记录的原始顺序

我想运行时最大的影响是调用函数和 可能不是分组本身。 如果要避免这种情况,可以尝试以下方法:

# create a column to restore the original order of the dataframe
df.reset_index(drop=True, inplace=True)
df.reset_index(drop=False, inplace=True)
df.columns= ['original_order'] + list(df.columns[1:])

# add a group column, that contains consecutive numbers if 
# two consecutive rows differ in at least one of the columns
# key, A, B
compare_columns= ['key', 'A', 'B']
df.sort_values(['key', 'original_order'], inplace=True)
df['group']= (df[compare_columns] != df[compare_columns].shift(1)).any(axis=1).cumsum()
df.drop_duplicates(['group'], keep='first', inplace=True)
df.drop(columns=['group'], inplace=True)
# now just restore the original index and it's order
df.set_index('original_order', inplace=True)
df.sort_index(inplace=True)
df
对此进行测试,结果是:

               key  A  B
original_order          
0                x  1  2
1                y  1  4
3                x  1  4
4                y  2  5
如果您不喜欢上面的索引名(
original\u order
),只需添加以下行即可将其删除:

df.index.name= None
测试数据:

from io import StringIO

infile= StringIO(
"""  key  A  B
0   x  1  2
1   y  1  4
2   x  1  2
3   x  1  4
4   y  2  5"""
)
df= pd.read_csv(infile, sep='\s+') #.set_index('Date')
df

是否存在这样一种情况,即
x
A
=
1
B
=
2
在数据帧中稍后出现时不会被删除?如果不是,我认为
drop_duplicates
with
subset=['key'、'A'、'B']
keep='first'
应该可以做到。是的,我扩展了上面的示例。删除重复项将不起作用。问题是关于连续复制,这就是为什么它如此棘手的原因。谢谢!这太棒了!关键部分似乎是分类。我最初没有尝试排序,因为我害怕快速排序O(n*logn)。我尝试了您的方法,对于数据帧大小,它比分组快得多。我想知道它是如何扩展的。事实上,它的速度快得令人难以置信。对于由200亿行组成的数据集,代码运行速度快了大约300到1000倍。感谢您的反馈。我很高兴这有帮助。我想这是因为调用了你的函数。因此,可能正因为如此,它无法在C代码中执行聚合逻辑,而是求助于python引擎。但这只是猜测。