【问题标题】:Check for duplicate values in Pandas dataframe column检查 Pandas 数据框列中的重复值
【发布时间】:2018-10-18 22:59:05
【问题描述】:

pandas 有没有办法检查数据框列是否有重复值,而不实际删除行?我有一个可以删除重复行的函数,但是,我只希望它在以下情况下运行在特定列中实际上存在重复项。

目前我将列中唯一值的数量与行数进行比较:如果唯一值的数量少于行数,则存在重复并且代码运行。

 if len(df['Student'].unique()) < len(df.index):
    # Code to remove duplicates based on Date column runs

有没有更简单或更有效的方法来检查特定列中是否存在重复值,使用 pandas?

我正在处理的一些示例数据(仅显示了两列)。如果找到重复项,则另一个函数会识别要保留的行(日期最早的行):

    Student Date
0   Joe     December 2017
1   James   January 2018
2   Bob     April 2018
3   Joe     December 2017
4   Jack    February 2018
5   Jack    March 2018

【问题讨论】:

  • 按日期排序您的 df,然后 df.drop_duplicates('student')
  • @Wen 是的,但可能会转换为日期时间并排序。快速检查将是:any(df['Student'].duplicated())
  • 几个误解:a) 从来没有必要检查len(df[col].unique()),pandas 有df[col].nunique() b) 但无论如何你甚至不需要那个,你只是在寻找对于df[col].duplicated(...)

标签: python pandas dataframe duplicates


【解决方案1】:

主要问题

列中是否存在重复值,True/False

╔═════════╦═══════════════╗
║ Student ║ Date          ║
╠═════════╬═══════════════╣
║ Joe     ║ December 2017 ║
╠═════════╬═══════════════╣
║ Bob     ║ April 2018    ║
╠═════════╬═══════════════╣
║ Joe     ║ December 2018 ║
╚═════════╩═══════════════╝

假设上述数据帧 (df),我们可以通过以下方式快速检查 Student col 中是否重复:

boolean = not df["Student"].is_unique      # True (credit to @Carsten)
boolean = df['Student'].duplicated().any() # True

进一步阅读和参考

上面我们使用的是 Pandas Series 方法之一。 pandas DataFrame 有几个有用的methods,其中两个是:

  1. drop_duplicates(self[, subset, keep, inplace]) - 返回删除重复行的DataFrame,可选地只考虑某些列。
  2. duplicated(self[, subset, keep]) - 返回表示重复行的布尔系列,可选择仅考虑某些列。

这些方法可以作为一个整体应用于 DataFrame,而不仅仅是上面的 Serie(列)。相当于:

boolean = df.duplicated(subset=['Student']).any() # True
# We were expecting True, as Joe can be seen twice.

但是,如果我们对整个框架感兴趣,我们可以继续做:

boolean = df.duplicated().any() # False
boolean = df.duplicated(subset=['Student','Date']).any() # False
# We were expecting False here - no duplicates row-wise 
# ie. Joe Dec 2017, Joe Dec 2018

最后一个有用的提示。通过使用keep 参数,我们通常可以跳过几行直接访问我们需要的内容:

keep : {‘first’, ‘last’, False}, 默认‘first’

  • first :删除除第一次出现的重复项。
  • last :删除除最后一次出现的重复项。
  • 错误:删除所有重复项。

使用示例

import pandas as pd
import io

data = '''\
Student,Date
Joe,December 2017
Bob,April 2018
Joe,December 2018'''

df = pd.read_csv(io.StringIO(data), sep=',')

# Approach 1: Simple True/False
boolean = df.duplicated(subset=['Student']).any()
print(boolean, end='\n\n') # True

# Approach 2: First store boolean array, check then remove
duplicate_in_student = df.duplicated(subset=['Student'])
if duplicate_in_student.any():
    print(df.loc[~duplicate_in_student], end='\n\n')

# Approach 3: Use drop_duplicates method
df.drop_duplicates(subset=['Student'], inplace=True)
print(df)

返回

True

  Student           Date
0     Joe  December 2017
1     Bob     April 2018

  Student           Date
0     Joe  December 2017
1     Bob     April 2018

【讨论】:

  • 谢谢,any(df['Student'].duplicated()) 是我所追求的。
  • 顺便说一句,我无法让日期转换工作(虽然我现有的功能确实有效)。我收到错误 AttributeError: 'DataFrame' object has no attribute 'Date' for line df['Date'] = pd.to_datetime(df.Date)
  • @JeffMitchell df.Date 等于 df['Date']。它区分大小写。你确定你的列被称为日期吗?也可以试试df['Date']
【解决方案2】:

你可以使用is_unique:

df['Student'].is_unique

# equals true in case of no duplicates

需要较旧的 pandas 版本:

pd.Series(df['Student']).is_unique

【讨论】:

  • 你只需要df['Student'].is_uniquedf['Student']已经是熊猫系列了
  • 诚然,较旧的 pandas 版本在这方面遇到了困难。现在编辑答案
【解决方案3】:

如果您想知道有多少重复项以及它们的用途:

df.pivot_table(index=['ColumnName'], aggfunc='size')

df.pivot_table(index=['ColumnName1',.., 'ColumnNameN'], aggfunc='size')

【讨论】:

    【解决方案4】:

    除了DataFrame.duplicatedSeries.duplicated,Pandas 还有一个DataFrame.anySeries.any

    import pandas as pd
    
    df = pd.read_csv("https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv")
    

    使用 Python ≥3.8,检查重复并访问一些重复的行:

    if (duplicated := df.duplicated(keep=False)).any():
        some_duplicates = df[duplicated].sort_values(by=df.columns.to_list()).head()
        print(f"Dataframe has one or more duplicated rows, for example:\n{some_duplicates}")
    

    【讨论】:

      猜你喜欢
      • 2020-12-31
      • 2018-06-13
      • 2021-06-26
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 2019-07-25
      • 2020-06-19
      • 2021-04-02
      相关资源
      最近更新 更多