首页 > 解决方案 > 动态删除多索引中的连续行

问题描述

我有一个df:

          pageid
sid vid
 1  ABC     dog
    ABC     dog
    ABC     dog
    ABC     dog
 2  DEF     cat
    DEF     cat
    DEF     pig
    DEF     cat
 3  GHI     pig
    GHI     cat
    GHI     dog
    GHI     dog

构造函数:

import pandas as pd

i = pd.MultiIndex.from_arrays(
    [[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
     ['ABC', 'ABC', 'ABC', 'ABC', 'DEF', 'DEF', 'DEF', 'DEF', 'GHI', 'GHI',
      'GHI', 'GHI']],
    names=('sid', 'vid')
)

df = pd.DataFrame({
    'pageid': ['dog', 'dog', 'dog', 'dog', 'cat', 'cat', 'pig', 'cat',
               'pig', 'cat', 'dog', 'dog']
}, index=i)

pageid如果它们存在于会话中,sid并且当且仅当它们是连续的,我想基本上从列中删除它们n。我发现的唯一示例使用 .shift() 如果我不必担心 n > 1 重复,它会很好地工作。不幸的是,在某些情况下,我得到了 n = 30 个连续重复项。

前:

          pageid
sid vid
 1  ABC     dog
    ABC     dog
    ABC     dog
    ABC     dog
 2  DEF     cat
    DEF     cat
    DEF     pig
    DEF     cat
 3  GHI     pig
    GHI     cat
    GHI     dog
    GHI     dog

后:

           pageid
sid vid
 1  ABC     dog
 2  DEF     cat
    DEF     pig
    DEF     cat
 3  GHI     pig
    GHI     cat
    GHI     dog

标签: pythonpandasdataframeduplicates

解决方案


全局重复

您可以reset_index计算duplicated

df[~df.reset_index().duplicated().values]

输出:

        pageid
sid vid       
1   ABC    dog
2   DEF    cat
    DEF    pig
3   GHI    pig
    GHI    cat
    GHI    dog

顺序重复

df2 = df[['pageid']].reset_index()
df[~df2.eq(df2.shift()).all(1).values]

输出:

        pageid
sid vid       
1   ABC    dog
2   DEF    cat
    DEF    pig
    DEF    cat
3   GHI    pig
    GHI    cat
    GHI    dog

具有阈值的顺序重复

thresh = 3

df2 = df[['pageid']].reset_index()
m = df2.eq(df2.shift()).all(1).groupby(df.set_index('pageid', append=True).index).cumsum()
df.loc[m.lt(thresh).values]

输出(示例阈值:3):

        pageid
sid vid       
1   ABC    dog
    ABC    dog
    ABC    dog
2   DEF    cat
    DEF    cat
    DEF    pig
    DEF    cat
3   GHI    pig
    GHI    cat
    GHI    dog
    GHI    dog

推荐阅读