重复值大作战:Duplicated与Drop_duplicates双剑合璧,还数据一片净土!
各位观众老爷,晚上好!欢迎来到“数据炼金术”课堂,我是你们的老朋友,数据界的扫地僧——阿甘! 今天,咱们不聊高大上的机器学习,不谈深奥的神经网络,就来聊聊数据清洗中一个看似不起眼,实则至关重要的话题:重复值处理!
想象一下,你辛辛苦苦收集了一大堆数据,结果发现里面掺杂着无数“双胞胎”、“三胞胎”,甚至“葫芦娃七兄弟”,这感觉是不是就像吃了一盘美味佳肴,结果发现里面混着几颗沙子,瞬间兴致全无? 😖
这些重复值就像数据里的“牛皮癣”,不仅会影响数据的准确性,还会干扰后续的分析结果,甚至误导决策!所以,我们要像对待自己的脸一样,认真清理这些“牛皮癣”,还数据一片净土!
而我们今天要介绍的两位主角,就是数据清洗界的“除癣双侠”:duplicated
和 drop_duplicates
! 它们就像一把锋利的剑和一把柔软的刷子,能够帮助我们轻松应对各种重复值问题。
第一幕:侦察兵 duplicated
,揪出潜藏的“双胞胎”!
duplicated
方法,顾名思义,就是用来检测数据中是否存在重复值的。它就像一个经验丰富的侦察兵,能够敏锐地发现潜藏在数据中的“双胞胎”!
duplicated
方法的基本语法如下:
DataFrame.duplicated(subset=None, keep='first')
让我们来逐个分析一下这些参数:
-
subset
: 这个参数就像侦察兵的放大镜,可以指定要检查重复值的列。如果不指定,默认会检查所有列。你可以传入一个列名字符串,或者一个包含多个列名的列表。- 例如,
subset='姓名'
表示只检查“姓名”列是否有重复值。 subset=['姓名', '年龄']
表示检查“姓名”和“年龄”两列的组合是否有重复值。
- 例如,
-
keep
: 这个参数就像侦察兵的策略,决定如何标记重复值。它有三个选项:'first'
(默认值): 将第一个出现的视为非重复值,后面的重复值标记为True
。 可以想象成,侦察兵发现了一对双胞胎,他会认为先遇到的那个是“原型”,后面的都是“复制品”。'last'
: 将最后一个出现的视为非重复值,前面的重复值标记为True
。 这次,侦察兵认为后遇到的那个是“原型”,前面的都是“复制品”。False
: 将所有重复值都标记为True
。 侦察兵一视同仁,只要是双胞胎,统统抓起来!
duplicated
方法返回的是一个布尔型的 Series,True
表示对应行是重复值,False
表示对应行不是重复值。
举个栗子 🌰:
假设我们有一个包含学生信息的数据集:
姓名 | 年龄 | 班级 |
---|---|---|
张三 | 18 | 一班 |
李四 | 19 | 二班 |
王五 | 18 | 一班 |
张三 | 18 | 一班 |
赵六 | 20 | 三班 |
李四 | 19 | 二班 |
现在,我们想要找出所有重复的学生信息,可以使用以下代码:
import pandas as pd
data = {'姓名': ['张三', '李四', '王五', '张三', '赵六', '李四'],
'年龄': [18, 19, 18, 18, 20, 19],
'班级': ['一班', '二班', '一班', '一班', '三班', '二班']}
df = pd.DataFrame(data)
duplicates = df.duplicated()
print(duplicates)
输出结果:
0 False
1 False
2 False
3 True
4 False
5 True
dtype: bool
可以看到,第3行和第5行被标记为 True
,表示它们是重复值。 默认使用 keep='first'
,因此第一行张三和李四被保留,后面的被标记为重复。
如果我们想只检查“姓名”列的重复值,可以这样做:
duplicates = df.duplicated(subset='姓名')
print(duplicates)
输出结果:
0 False
1 False
2 False
3 True
4 False
5 True
dtype: bool
这次,只有姓名重复的行被标记为 True
。
如果我们想保留最后一个出现的记录,可以使用 keep='last'
:
duplicates = df.duplicated(keep='last')
print(duplicates)
输出结果:
0 True
1 True
2 False
3 False
4 False
5 False
dtype: bool
可以看到,这次第一行和第二行被标记为 True
,表示它们是重复值,保留了最后出现的记录。
如果我们想把所有重复值都标记为 True
,可以使用 keep=False
:
duplicates = df.duplicated(keep=False)
print(duplicates)
输出结果:
0 True
1 True
2 False
3 True
4 False
5 True
dtype: bool
可以看到,所有重复的行都被标记为 True
。
第二幕:清道夫 drop_duplicates
,一键删除“牛皮癣”!
drop_duplicates
方法就像一个高效的清道夫,能够根据指定的规则,一键删除数据中的重复值,还数据一片干净!
drop_duplicates
方法的基本语法如下:
DataFrame.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)
让我们来逐个分析一下这些参数:
-
subset
: 这个参数和duplicated
方法中的subset
参数一样,指定要检查重复值的列。如果不指定,默认会检查所有列。 -
keep
: 这个参数也和duplicated
方法中的keep
参数一样,决定如何保留重复值。 -
inplace
: 这个参数决定是否在原 DataFrame 上进行修改。True
: 在原 DataFrame 上直接删除重复值。False
(默认值): 返回一个新的 DataFrame,包含删除重复值后的结果,原 DataFrame 不变。
-
ignore_index
: 这个参数决定是否重置索引。True
: 重置索引,使索引从 0 开始连续排列。False
(默认值): 保留原索引。
举个栗子 🌰:
还是用上面的学生信息数据集:
import pandas as pd
data = {'姓名': ['张三', '李四', '王五', '张三', '赵六', '李四'],
'年龄': [18, 19, 18, 18, 20, 19],
'班级': ['一班', '二班', '一班', '一班', '三班', '二班']}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
df_no_duplicates = df.drop_duplicates()
print("n删除重复值后的数据:")
print(df_no_duplicates)
输出结果:
原始数据:
姓名 年龄 班级
0 张三 18 一班
1 李四 19 二班
2 王五 18 一班
3 张三 18 一班
4 赵六 20 三班
5 李四 19 二班
删除重复值后的数据:
姓名 年龄 班级
0 张三 18 一班
1 李四 19 二班
2 王五 18 一班
4 赵六 20 三班
可以看到,重复的行被成功删除,并返回了一个新的 DataFrame。
如果我们想在原 DataFrame 上直接删除重复值,可以这样做:
df.drop_duplicates(inplace=True)
print("n删除重复值后的数据(原DataFrame):")
print(df)
输出结果:
删除重复值后的数据(原DataFrame):
姓名 年龄 班级
0 张三 18 一班
1 李四 19 二班
2 王五 18 一班
4 赵六 20 三班
这次,原 DataFrame 上的重复值也被删除了。
如果我们想只根据“姓名”列删除重复值,可以这样做:
df_no_duplicates = df.drop_duplicates(subset='姓名')
print("n只根据姓名删除重复值后的数据:")
print(df_no_duplicates)
输出结果:
只根据姓名删除重复值后的数据:
姓名 年龄 班级
0 张三 18 一班
1 李四 19 二班
2 王五 18 一班
4 赵六 20 三班
这次,只有姓名重复的行被删除。
如果我们想保留最后一个出现的记录,可以使用 keep='last'
:
df_no_duplicates = df.drop_duplicates(keep='last')
print("n保留最后出现的记录:")
print(df_no_duplicates)
输出结果:
保留最后出现的记录:
姓名 年龄 班级
2 王五 18 一班
3 张三 18 一班
4 赵六 20 三班
5 李四 19 二班
可以看到,这次保留了最后出现的记录。
如果我们想重置索引,可以使用 ignore_index=True
:
df_no_duplicates = df.drop_duplicates(ignore_index=True)
print("n重置索引后的数据:")
print(df_no_duplicates)
输出结果:
重置索引后的数据:
姓名 年龄 班级
0 张三 18 一班
1 李四 19 二班
2 王五 18 一班
3 赵六 20 三班
可以看到,索引被重置为从 0 开始的连续排列。
第三幕:实战演练,让数据更完美!
说了这么多理论,让我们来做一些实战演练,巩固一下所学知识!
场景一:电商平台用户数据清洗
假设我们有一个电商平台的用户数据,包含以下字段:
user_id
: 用户IDusername
: 用户名email
: 邮箱phone
: 手机号address
: 地址
我们发现有些用户注册了多个账号,但邮箱和手机号都相同,这属于恶意注册行为,需要清理掉。
import pandas as pd
data = {'user_id': [1, 2, 3, 4, 5, 6],
'username': ['张三', '李四', '王五', '张三', '赵六', '李四'],
'email': ['[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]'],
'phone': ['13800000001', '13800000002', '13800000003', '13800000001', '13800000004', '13800000002'],
'address': ['北京', '上海', '广州', '北京', '深圳', '上海']}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
# 根据邮箱和手机号删除重复值
df_no_duplicates = df.drop_duplicates(subset=['email', 'phone'], keep='first')
print("n删除重复值后的数据:")
print(df_no_duplicates)
在这个例子中,我们根据 email
和 phone
两列删除重复值,保留第一个出现的记录。
场景二:在线教育平台课程数据清洗
假设我们有一个在线教育平台的课程数据,包含以下字段:
course_id
: 课程IDcourse_name
: 课程名称teacher
: 授课老师duration
: 课程时长 (分钟)price
: 课程价格 (元)
我们发现有些课程的信息完全一样,这可能是由于数据录入错误导致的,需要清理掉。
import pandas as pd
data = {'course_id': [1, 2, 3, 4, 5, 6],
'course_name': ['Python入门', 'Java进阶', '数据分析', 'Python入门', 'Web开发', 'Java进阶'],
'teacher': ['张老师', '李老师', '王老师', '张老师', '赵老师', '李老师'],
'duration': [60, 90, 120, 60, 100, 90],
'price': [99, 199, 299, 99, 149, 199]}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
# 删除所有完全重复的行
df_no_duplicates = df.drop_duplicates()
print("n删除重复值后的数据:")
print(df_no_duplicates)
在这个例子中,我们没有指定 subset
参数,因此 drop_duplicates
方法会检查所有列,删除所有完全重复的行。
总结陈词:双剑合璧,天下无敌!
今天,我们学习了如何使用 duplicated
和 drop_duplicates
这两个方法来处理数据中的重复值。duplicated
方法就像一个侦察兵,能够帮助我们找出潜藏的“双胞胎”,而 drop_duplicates
方法就像一个清道夫,能够一键删除这些“牛皮癣”,还数据一片干净!
这两个方法就像一对形影不离的好伙伴,可以根据不同的需求灵活搭配使用。掌握了它们,你就可以轻松应对各种重复值问题,让数据更加准确、可靠,为后续的分析工作打下坚实的基础!
记住,数据清洗是数据分析的重要一步,就像盖房子打地基一样,地基打得越牢固,房子才能盖得越高! 希望大家能够熟练运用 duplicated
和 drop_duplicates
这两把利器,打造出高质量的数据集,在数据分析的道路上越走越远! 🚀
好了,今天的“数据炼金术”课堂就到这里,感谢大家的观看!咱们下期再见! 👋