处理 Pandas DataFrame 中的重复值

处理 Pandas DataFrame 中的重复值

介绍

作为数据分析师,我们有责任确保数据完整性以获得准确且值得信赖的见解。 数据清理在此过程中起着至关重要的作用,重复值是数据分析师遇到的最常见问题之一。 重复值可能会歪曲见解。 因此,拥有处理重复值的有效方法至关重要。 在本文中,我们将学习如何识别和处理重复值,以及管理重复项的最佳实践。

识别重复值

处理重复值的第一步是识别它们。 识别重复值是数据清理的重要步骤。 Pandas 提供了多种方法来识别数据框中的重复值。 在本节中,我们将讨论 duplicated() 功能和 value_counts() 用于识别重复值的函数。

使用设 重复的()

duplicated() function 是一个 Pandas 库函数,用于检查 DataFrame 中的重复行。 的输出 duplicated() function 是一个与输入 DataFrame 长度相同的布尔系列,其中每个元素表示相应的行是否重复。

让我们考虑一个简单的例子 duplicated() 功能:

import pandas as pd data = { 'StudentName': ['Mark', 'Ali', 'Bob', 'John', 'Johny', 'Mark'], 'Score': [45, 65, 76, 44, 39, 45]
}
df = pd.DataFrame(data) df_duplicates = df.duplicated()
print(df_duplicates)

输出:

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

在上面的示例中,我们创建了一个包含学生姓名及其总分的 DataFrame。 我们调用了 duplicated() 在 DataFrame 上,它生成了一个布尔系列 False 代表独特的价值和 True 表示重复值。

在此示例中,值的第一次出现被认为是唯一的。 但是,如果我们希望最后一个值被认为是唯一的,并且我们不想在识别重复值时考虑所有列呢? 在这里,我们可以修改 duplicated() 通过改变参数值的功能。

参数:子集和保留

duplicated() 函数通过其可选参数提供自定义选项。 它有两个参数,如下所述:

  • subset:此参数使我们能够指定在重复检测期间要考虑的列子集。 子集设置为 None 默认情况下,这意味着考虑 DataFrame 中的每一列。 要指定列名,我们可以为子集提供列名列表。

    下面是使用 subset 参数的示例:

    
    df_duplicates = df.duplicated(subset=['StudentName'])
    

    输出:

    0 False
    1 False
    2 False
    3 False
    4 False
    5 True
    dtype: bool
    
  • keep:此选项允许我们选择重复行的哪个实例应标记为重复。 keep 的可能值为:

    • "first": 这是默认值 keep 选项。 它识别除第一次出现以外的所有重复项,认为第一个值是唯一的。
    • "last":此选项将最后一次出现标识为唯一值。 所有其他事件将被视为重复。
    • False:此选项将每个实例标记为重复值。

下面是一个使用 keep 参数:


df_duplicates = df.duplicated(keep='last')
print(df_duplicates)

输出:

0 True
1 False
2 False
3 False
4 False
5 False
dtype: bool
可视化重复值

value_counts() 函数是识别重复项的第二种方法。 这 value_counts() 函数计算每个唯一值在列中出现的次数。 通过应用 value_counts() 对特定列的函数,可以可视化每个值的频率。

下面是一个使用 value_counts() 功能:

import matplotlib.pyplot as plt
import pandas as pd data = { 'StudentName': ['Mark', 'Ali', 'Bob', 'John', 'Johny', 'Mark'], 'Score': [45, 65, 76, 44, 39, 45]
}
df = pd.DataFrame(data) name_counts = df['StudentName'].value_counts()
print(name_counts)

输出:

Mark 2
Ali 1
Bob 1
John 1
Johny 1
Name: StudentName, dtype: int64

现在让我们用条形图可视化重复值。 我们可以使用条形图有效地可视化重复值的频率。


name_counts.plot(kind='bar')
plt.xlabel('Student Name')
plt.ylabel('Frequency')
plt.title('Duplicate Name Frequencies')
plt.show()

重复值

处理重复值

识别出重复值后,就该解决它们了。 在本节中,我们将探讨使用 pandas 删除和更新重复值的各种策略 drop_duplicates()replace() 功能。 此外,我们将讨论使用 groupby() 功能。

删除重复值

处理重复项的最常见方法是将它们从 DataFrame 中删除。 为了从 DataFrame 中消除重复记录,我们将使用 drop_duplicates() 功能。 默认情况下,此函数保留每个重复行的第一个实例并删除后续出现的实例。 它根据所有列值识别重复值; 但是,我们可以使用子集参数指定要考虑的列。

的语法 drop_duplicates() 参数中的默认值如下:

dataFrame.drop_duplicates(subset=None, keep='first', inplace=False)

subsetkeep 参数具有与中相同的解释 duplicates(). 如果我们设置第三个参数 inplaceTrue,所有修改将直接在原始 DataFrame 上执行,导致方法返回 None 以及正在修改的原始 DataFrame。 默认情况下, inplace is False.

这是一个例子 drop_duplicates() 功能:


df.drop_duplicates(keep='last', inplace=True)
print(df)

输出:

 StudentName Score
1 Ali 65
2 Bob 76
3 John 44
4 Johny 39
5 Mark 45

查看我们的 Git 学习实践指南,其中包含最佳实践、行业认可的标准以及随附的备忘单。 停止谷歌搜索 Git 命令,实际上 学习 它!

在上面的示例中,第一个条目被删除,因为它是重复的。

替换或更新重复值

处理重复项的第二种方法涉及使用 Pandas 替换值 replace() 功能。 的 replace() 函数允许我们用新值替换 DataFrame 中的特定值或模式。 默认情况下,它会替换该值的所有实例。 但是,通过使用 limit 参数,我们可以限制替换的次数。

下面是一个使用 replace() 功能:


df['StudentName'].replace('Mark', 'Max', limit=1, inplace=True)
print(df)

输出:

 StudentName Score
0 Max 45
1 Ali 65
2 Bob 76
3 John 44
4 Johny 39
5 Mark 45

在这里,限制用于替换第一个值。 如果我们想替换最后一次出现怎么办? 在这种情况下,我们将结合 duplicated()replace() 职能。 使用 duplicated(),我们将指示每个重复值的最后一个实例,使用 loc 函数,然后使用 replace() 功能。 这是一个使用的例子 duplicated()replace() 一起发挥作用。


last_occurrences = df.duplicated(subset='StudentName', keep='first') last_occurrences_rows = df[last_occurrences] df.loc[last_occurrences, 'StudentName'] = df.loc[last_occurrences, 'StudentName'].replace('Mark', 'Max') print(df)

输出:

 StudentName Score
0 Mark 45
1 Ali 65
2 Bob 76
3 John 44
4 Johny 39
5 Max 45

复杂替换的自定义函数

在某些情况下,处理重复值需要比简单地删除或更新它们更复杂的替换。 自定义功能使我们能够创建适合我们需求的特定替换规则。 通过使用熊猫 apply() 函数,我们可以将自定义函数应用于我们的数据。

例如,假设“StudentName”列包含重复姓名。 我们的目标是使用自定义函数替换重复值,该函数在重复值的末尾附加一个数字,使它们独一无二。


def add_number(name, counts): if name in counts: counts[name] += 1 return f'{name}_{counts[name]}' else: counts[name] = 0 return name name_counts = {} df['is_duplicate'] = df.duplicated('StudentName', keep=False)
df['StudentName'] = df.apply(lambda x: add_number(x['StudentName'], name_counts) if x['is_duplicate'] else x['StudentName'], axis=1)
df.drop('is_duplicate', axis=1, inplace=True)
print(df)

输出:

 StudentName Score
0 Mark 45
1 Ali 65
2 Bob 76
3 John 44
4 Johny 39
5 Mark_1 45

聚合具有重复值的数据

可以聚合包含重复值的数据以汇总数据并从中获得洞察力。 熊猫 groupby() 函数允许您聚合具有重复值的数据。 通过使用 groupby() 函数,您可以对一个或多个列进行分组,并为每个组计算另一列的平均值、中位数或总和。

下面是一个使用 groupby() 方法:


grouped = df.groupby(['StudentName']) df_aggregated = grouped.sum()
print(df_aggregated)

输出:

 Score
StudentName Ali 65
Bob 76
John 44
Johny 39
Mark 90

高级技巧

为了处理更复杂的场景并确保准确的分析,我们可以使用一些高级技术。 本节将讨论处理模糊重复、时间序列数据中的重复和重复索引值。

模糊重复

模糊重复是不完全匹配但相似的记录,它们的发生可能有多种原因,包括数据输入错误、拼写错误和格式变化。 我们将使用 fuzzywuzzy 使用字符串相似性匹配识别重复项的 Python 库。

下面是一个处理模糊值的例子:

import pandas as pd
from fuzzywuzzy import fuzz def find_fuzzy_duplicates(dataframe, column, threshold): duplicates = [] for i in range(len(dataframe)): for j in range(i+1, len(dataframe)): similarity = fuzz.ratio(dataframe[column][i], dataframe[column][j]) if similarity >= threshold: duplicates.append(dataframe.iloc[[i, j]]) if duplicates: duplicates_df = pd.concat(duplicates) return duplicates_df else: return pd.DataFrame() data = { 'StudentName': ['Mark', 'Ali', 'Bob', 'John', 'Johny', 'Mark'], 'Score': [45, 65, 76, 44, 39, 45]
}
df = pd.DataFrame(data) threshold = 70 fuzzy_duplicates = find_fuzzy_duplicates(df, 'StudentName', threshold)
print("Fuzzy duplicates:")
print(fuzzy_duplicates.to_string(index=False))

在这个例子中,我们创建一个自定义函数 find_fuzzy_duplicates 它将 DataFrame、列名和相似度阈值作为输入。 该函数遍历 DataFrame 中的每一行,并使用 fuzz.ratio 的方法 fuzzywuzzy 图书馆。 如果相似度分数大于或等于阈值,则将重复行添加到列表中。 最后,该函数返回一个包含模糊重复项的 DataFrame。

输出:

Fuzzy duplicates:
StudentName Score Mark 45 Mark 45 John 44 Johny 39

在上面的示例中,在“StudentName”列中标识了模糊重复项。 'find_fuzzy_duplicates' 函数使用 fuzzywuzzy 图书馆的 fuzz.ratio 函数,它根据 Levenshtein 距离计算相似性分数。 我们将阈值设置为 70,这意味着匹配率大于 70 的任何名称都将被视为模糊值。 识别模糊值后,我们可以使用标题为“处理重复项”的部分中概述的方法来管理它们。

处理时间序列数据重复

当在同一时间戳记录多个观察时,可能会出现重复。 如果处理不当,这些值可能会导致有偏差的结果。 以下是处理时间序列数据中重复值的几种方法。

  • 删除精确的重复项:在此方法中,我们使用 drop_duplicates 在熊猫中发挥作用。
  • 具有不同值的重复时间戳:如果我们有相同的时间戳但不同的值,我们可以聚合数据并使用 groupby(),或者我们可以选择最近的值并使用删除其他值 drop_duplicates()keep 参数设置为“最后”。

处理重复的索引值

在解决重复的索引值之前,让我们首先定义什么是 Pandas 中的索引。 索引是分配给 DataFrame 的每一行的唯一标识符。 Pandas 默认分配一个从零开始的数字索引。 但是,可以将索引分配给任何列或列组合。 要识别索引列中的重复项,我们可以使用 duplicated()drop_duplicates() 功能,分别。 在本节中,我们将探索如何使用 Index 列处理重复项 reset_index().

顾名思义, reset_index() Pandas 中的函数用于重置 DataFrame 的索引。 当应用 reset_index() 函数,当前索引被自动丢弃,即初始索引值丢失。 通过指定 drop 参数为 False ,在 reset_index() 函数,我们可以在重置索引的同时保留原始索引值。

这是一个使用示例 reset_index():

import pandas as pd data = { 'Score': [45, 65, 76, 44, 39, 45]
}
df = pd.DataFrame(data, index=['Mark', 'Ali', 'Bob', 'John', 'Johny', 'Mark']) df.reset_index(inplace=True)
print(df)

输出:

 index Score
0 Mark 45
1 Ali 65
2 Bob 76
3 John 44
4 Johny 39
5 Mark 45

最佳实践

  • 了解重复数据的性质:在采取任何行动之前,了解为什么存在重复值及其代表什么是至关重要的。 确定根本原因,然后确定处理这些问题的适当步骤。

  • 选择适当的方法来处理重复项:如前几节所述,有多种方法可以处理重复项。 您选择的方法取决于数据的性质和您打算执行的分析。

  • 记录方法:记录检测重复值并解决它们的过程非常重要,让其他人能够理解思维过程。

  • 注意运动:每当我们删除或修改数据时,我们必须确保删除重复项不会在分析中引入错误或偏差。 进行完整性测试并验证每个操作的结果。

  • 保留原始数据:在对数据进行任何操作之前,请创建原始数据的备份副本。

  • 防止将来重复:采取措施防止将来发生重复。 这可以包括数据输入期间的数据验证、数据清理例程或强制唯一性的数据库约束。

最后的思考

在数据分析中,解决重复值是至关重要的一步。 重复的值会导致不准确的结果。 通过有效地识别和管理重复值,数据分析师可以获得准确且重要的信息。 实施上述技术并遵循最佳实践将使分析师能够保持数据的完整性并从中提取有价值的见解。

时间戳记:

更多来自 堆栈滥用