如果两列中的连续值相同,如何在python中删除重复项?

时间:2019-09-18 09:17:30

标签: python pandas dataframe

我有一个如下数据框:

A   B   C
1   8   23
2   8   22
3   9   45
4   9   45
5   6   12
6   4   10
7   11  12

我想删除重复项,如果C也相同,则在连续出现的地方保留第一个值。 例如,此处发生的“ 9”是B列是重复的,并且它们在列“ C”中的对应的出现也是重复的“ 45”。在这种情况下,我想保留第一次出现的情况。

预期输出:

A   B   C
1   8   23
2   8   22
3   9   45
5   6   12
6   4   10
7   11  12

我尝试了一些分组方式,但不知道该如何放弃。

代码:

df['consecutive'] = (df['B'] != df['B'].shift(1)).cumsum()
test=df.groupby('consecutive',as_index=False).apply(lambda x: (x['B'].head(1),x.shape[0],
                                                       x['C'].iloc[-1] - x['C'].iloc[0]))

该分组返回给我一个系列,但我想删除。

7 个答案:

答案 0 :(得分:2)

在两列中添加DataFrame.drop_duplicates

df['consecutive'] = (df['B'] != df['B'].shift(1)).cumsum()
df = df.drop_duplicates(['consecutive','C'])
print (df)
   A   B   C  consecutive
0  1   8  23            1
1  2   8  22            1
2  3   9  45            2
4  5   6  12            3
5  6   4  10            4
6  7  11  12            5

或将两个条件与|链接以按位OR

df = df[(df['B'] != df['B'].shift()) | (df['C'] != df['C'].shift())]
print (df)
   A   B   C
0  1   8  23
1  2   8  22
2  3   9  45
4  5   6  12
5  6   4  10
6  7  11  12

答案 1 :(得分:1)

一个可以过滤掉此类记录的单线纸是:

df[(df[['B', 'C']].shift() != df[['B', 'C']]).any(axis=1)]

因此,在此我们检查列['B', 'C']是否与移位的行相同,否则,我们保留以下值:

>>> df[(df[['B', 'C']].shift() != df[['B', 'C']]).any(axis=1)]
   A   B   C
0  1   8  23
1  2   8  22
2  3   9  45
4  5   6  12
5  6   4  10
6  7  11  12

这是相当可扩展的,因为我们可以定义一个函数,可以轻松地对任意数量的值进行操作:

def drop_consecutive_duplicates(df, *colnames):
    dff = df[list(colnames)]
    return df[(dff.shift() != dff).any(axis=1)]

因此您可以使用以下内容进行过滤:

drop_consecutive_duplicates(df, 'B', 'C')

答案 2 :(得分:1)

检查B行和C行之间差异的简单方法,如果差异为0(重复值),则丢弃该值,代码为

driver.findElement(By.name("Upload")).click();
driver.findElement(By.xpath("//textarea[@name='Upload']")).click();

答案 3 :(得分:1)

axis=1上使用diffneany

注意:此方法仅适用于数字列

m = df[['B', 'C']].diff().ne(0).any(axis=1)
print(df[m])

输出

   A   B   C
0  1   8  23
1  2   8  22
2  3   9  45
4  5   6  12
5  6   4  10
6  7  11  12

详细信息

df[['B', 'C']].diff()

     B     C
0  NaN   NaN
1  0.0  -1.0
2  1.0  23.0
3  0.0   0.0
4 -3.0 -33.0
5 -2.0  -2.0
6  7.0   2.0

然后我们检查一行中的值anyne是否不相等(0):

df[['B', 'C']].diff().ne(0).any(axis=1)

0     True
1     True
2     True
3    False
4     True
5     True
6     True
dtype: bool

答案 4 :(得分:0)

您可以计算要删除的一系列行,然后删除它们:

to_drop = (df['B'] == df['B'].shift())&(df['C']==df['C'].shift())
df = df[~to_drop]

它给出了预期的结果:

   A   B   C
0  1   8  23
1  2   8  22
2  3   9  45
4  5   6  12
5  6   4  10
6  7  11  12

答案 5 :(得分:0)

代码

df1 = df.drop_duplicates(subset=['B', 'C'])  

结果

   A   B   C
0  1   8  23
1  2   8  22
2  3   9  45
4  5   6  12
5  6   4  10
6  7  11  12

答案 6 :(得分:0)

如果我正确理解了您的问题,请考虑以下数据框:

df = pd.DataFrame({'B': [8, 8, 9, 9, 6, 4, 11], 'C': [22, 23, 45, 45, 12, 10, 12],})

此单行代码使用drop_duplicates方法解决了您的问题:

df.drop_duplicates(['B', 'C'])

它给出了预期的结果:

    B   C
0   8  22
1   8  23
2   9  45
4   6  12
5   4  10
6  11  12