【问题标题】:Filter out the rows which contain the duplicate value only in the previous row过滤掉仅在前一行中包含重复值的行
【发布时间】:2020-12-19 02:31:51
【问题描述】:

我正在使用 Python 和 pandas 库。我有一个数据框 df。我需要编写一个函数来过滤掉重复项,也就是说,删除与上面一行包含相同值的行

示例:

df = pd.DataFrame({'A': {0: 1, 1: 2, 2: 2, 3: 3, 4: 4, 5: 5, 6: 5, 7: 5, 8: 6, 9: 7, 10: 7}, 'B': {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k'}})

我在下面写了代码。

total_len = len(df.index)
for i in range(total_len):
        if df['A'].loc[i] == df['A'].loc[i+1]: 
            df['A'].drop(df['A'].index[i+1])
        else:
            df['A']

我做错了什么?

【问题讨论】:

标签: pandas dataframe filter duplicates


【解决方案1】:

您的代码的问题是此 df 的范围是 0-10(11 行)。但是,当您使用 df['A'].loc[i+1] 时,当 i = 10 时,它会搜索 i+1 行进行比较,但该行不存在。因此KeyError 11

total_len = len(df.index)
for i in range(total_len):
        if df['A'].loc[i] == df['A'].loc[i+1]: 
            df['A'].drop(df['A'].index[i+1])
        else:
            df['A']
#ERROR            
KeyError: 11   

相反,解决此问题的更好方法是简单地从第二行开始迭代,比较之前的行,以获得标志 TrueFalse 的列表。然后你可以用它来过滤 df -

dup = [True]

total_len = len(df.index)
for i in range(1, total_len):
    if df.iloc[i]['A'] == df.iloc[i-1]['A']:
        dup.append(False)
    else:
        dup.append(True)
        
print(df[dup])
   A  B
0  1  a
1  2  b
3  3  d
4  4  e
5  5  f
8  6  i
9  7  j

【讨论】:

  • 感谢您解释我的代码中的问题并提供替代方案。我测试了代码并添加了reset.index()。谢谢
  • @lomye - 很高兴为您提供帮助。如果此答案帮助您解决了问题,请将其标记为正确的答案!
【解决方案2】:

不用循环也可以做到

df = df[ # filter df with a boolean array
    df.A.ne(df.A.shift()) # find out if elements are different from the row above
]

【讨论】:

  • 不错的方法。我可以添加df[df.ne(df.shift())['A']] 也可以。
  • 是的,这也可以,但是你比较所有的列是不必要的,用宽 df 比较慢
  • 我也建议不要使用点符号来引用列。
  • @ScottBoston 同意,我以为您是在说这段代码会失败...值得知道,但由于 OP 很好地使用标准索引,所以没有考虑它
猜你喜欢
  • 1970-01-01
  • 2022-10-21
  • 1970-01-01
  • 2012-08-01
  • 2020-03-29
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
相关资源
最近更新 更多