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