我正在删除数据框中成组的连续重复项。我正在寻找比这更快的方法:
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
中的连续重复项。
答案 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