删除组的连续重复项

时间:2020-10-08 15:02:29

标签: 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

# 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中的连续重复项。

1 个答案:

答案 0 :(得分:1)

根据您的代码,如果行之间出现在下面,则只删除行 它们按关键字分组。因此,中间有另一个键的行不会影响此逻辑。但是,这样做时,您想保留记录的原始顺序。

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

# 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_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