0、前言:
- 使用pandas修改数据是否会改变源数据?
- 以下操作,都来自调用表格导入数据
import pandas as pd
df = pd.read_excel('./data/demo_06.xlsx', sheet_name='Sheet1')
1、处理缺失值:
- 理解:对于所获取数据中如果有缺失值(空值),可以通过查找缺失值、填充缺失值、删除缺失值的方法来处理
- 通过查看字段信息检查是否有缺失值:df.info()
- 查看每列空值数量:df.isnull().sum() # 显示每列空值总数
- 查看每列是否存在空值:
# any: or 或
df.isnull().any()
- 填充缺失值:
- 填充缺失值方法
- 均值(mean):正态分布
- 众数(mode):分类变量
- 中位数(median):非正态分布
# 众数可能存在多个,通过众数填充
most = df['类别'].mode()[0]
df['类别'] = df['类别'].fillna(most)
# 向前填充,forward
df['类别'] = df['类别'].fillna(method='ffill')
# 向后填充,backward
df['类别'] = df['类别'].fillna(method='bfill')
# 删除存在空值的行,整表判断
df.dropna()
# 删除指定列存在空值的行,其中一列存在空值则删除整行(or)
df.dropna(how='any', subset=['产品数量', '类别'])
# 删除指定列存在空值的行,指定列都存在空值则删除整行(and)
df.dropna(how='all', subset=['产品数量', '类别'])
# 删除非空值小于4个的行(不删存在4个非空值的行)
df.dropna(thresh=4)
2、处理重复值:
- 理解:对于所获取数据中如果有重复值,可以通过判断是否有重复值、删除重复值的方法来处理
- 查看每行是否完全重复:df.duplicated()
- 删除整行完全重复的数据:df.drop_duplicates(keep=‘last’) # keep是指保留重复数据的哪一条
- 用列索引作为判断依据,如果有重复则删除改列对应重复值所在的行:
- df.drop_duplicates(subset=‘用户ID’, keep=‘first’)
- df.drop_duplicates(subset=[‘用户ID’, ‘产品名称’], keep=‘last’)
3、数据筛选:
- 理解:对于所获取数据中如果有重复值,可以给通过数据筛选来显示满足对应列索引要求的数据
- query方法筛选(and、or、not,&、|、~)
- 数值范围筛选
- 时间段筛选(先转化为索引,再筛选)
# 数值筛选
df.query('产品数量 >= 2')
# 文本筛选
df.query('类别 == "优选"')
# df.query("类别 == '优选'")
# 组合筛选
df.query('类别 == "优选" and 产品数量 >= 2')
# 左包含右包含
df[df['产品数量'].between(3, 5)]
# 筛选时间段在12:00:00-23:00:00之间的数据
tb = df.set_index('订单付款时间')
tb.between_time('12:00:00', '23:00:00')
# 时间点筛选
tb = df.set_index('订单付款时间')
tb.at_time('22:54:26')
4、数据清洗:
- 理解:对于所获取数据中如果有重复值,可以通过pandas中的高级函数来修改对应内容
- 普通方法筛选:df.filter(items=[‘用户ID’, ‘产品清单’])
- 正则方法筛选:df.filter(regex=‘用户ID|第\d+次交易金额’)
- 特殊操作:
# 字段合并
pd.Series.str.cat()
df['基本信息'] = df['性别'].str.cat(df['年龄'], sep=',')
内容替换
pd.Series.str.replace()
df['交易金额'].str.replace('元', '').astype(int)
# astype(int)是把操作结束的数据转为整型
信息提取
pd.Series.str.extract()
df['手机号码'] = df['联系方式'].str.extract(pat='(\d{11})', expand=True)
# 爆炸序列:一行拆分成多行
tb = df[['用户ID', '产品清单']].copy()
# split+explode
tb['产品清单'] = tb['产品清单'].str.split(',', expand=False)
tb = tb.explode(column='产品清单', ignore_index=True)
# ignore_index=True:目的是把分裂出的行重新排序,否则,分裂出的行会沿用之前的索引行号
# 文本聚合:多行合并成一行
df[['用户ID', '产品清单']]
tb.groupby('用户ID', as_index=False).agg(lambda x: ','.join(x))