看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在本例中,我们将充分利用 pandas 的底层 NumPy 提供的广播机制来对问题数据进行处理。理解和熟练掌握广播机制,对玩们处理数据阵列问题有重要的意义,它将我们带到一个全新的数据思维体系,帮助我们高效进行数据挖掘。
我们先把数据构造出来:
from io import StringIO
import pandas as pd
data = '''
姓名 出生年月 2010-01 2010-02 2010-03
A 2010-02 1.0 1.0 1.0
B 2010-09 NaN NaN 1.0
C 2010-01 1.0 2.0 3.0
'''
df = pd.read_csv(StringIO(data), sep=r'\s+')
df
# ...
发上数据,每一行代表一个人在不同的时间所花费的金额,但是在数据中姓名 A 和 C 的数据是有问题的,因为他们在他们还没出生的时候就有消费额,现在想把这部分的错数据去掉,填充为缺失值。
即:出生日期列的时间大于对应列上时间时,数据保留,否则去除,填充为缺失值。
数据需求的描述,我们本能的想法可能是按行进行迭代计算,或者将数据转对堆叠(用 stack() 方法)来解决。
但此问题是一个典型的一个日期对一个日期数组的操作,比如出生年月 (2010-02、2010-09、2010-01)
这个数组与列名中的日期 2010-01 的操作(数组与标量),它们之间进行比较操作(>),比较得到一个布尔序列,为 True 点位的数据则代表相应表的日期大于出生日间,就是符合要求的数据,需要保留,否则就要删除。
得到布尔矩阵后,我们用 mask() 方法来替换 Ture 值。
我们先做一个上述思路中的实验:
# 数组(出生年月序列)与标量(第三个列名 2010-01)操作
df.出生年月 > df.columns[2]
'''
0 True
1 True
2 False
Name: 出生年月, dtype: bool
'''
我们发现,可以实现字符串之间的比较操作,如姓名列返回了 False,其他日期字符串也得到了正确的布尔值,这样省去了我们格式转换及类型转换的操作。
我们用 apply() 对所有列进行这个操作,整个 DataFrame 就成为了一个布尔矩阵:
df.apply(lambda x: df.出生年月 > x.name)
'''
姓名 出生年月 2010-01 2010-02 2010-03
0 False False True False False
1 False False True True True
2 False False False False False
'''
mask() 可以替换 Ture 值,我们将他们替换为 None:
df.mask(df.apply(lambda x: df.出生年月 > x.name), None)
'''
姓名 出生年月 2010-01 2010-02 2010-03
0 A 2010-02 NaN 1.0 1.0
1 B 2010-09 NaN NaN NaN
2 C 2010-01 1.0 2.0 3.0
'''
这样数据就得到了处理,我们也完成了需求。
(完)
更新时间:2024-08-18 16:00:09 标签:pandas python 广播 数据清洗