python数据整合_Python的数据整合与数据清洗!都是基于Pandas!史上最详细教程!...

每次爬虫获取的数据都是需要处理下的。

所以这一次简单讲一下Pandas的用法,以便以后能更好的使用。

数据整合是对数据进行行列选择、创建、删除等操作。

数据清洗则是将整合好的数据去除其中的错误和异常。

本期利用之前获取的网易云音乐用户数据,来操作一番。

/ 01 / 数据整合

首先读取数据。

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

# 设置列名与数据对齐

pd.set_option('display.unicode.ambiguous_as_wide', True)

pd.set_option('display.unicode.east_asian_width', True)

# 显示所有列

pd.set_option('display.max_columns', None)

# 显示10行

pd.set_option('display.max_rows', 10)

# 设置显示宽度为1000,这样就不会在IDE的输出框中换行了

pd.set_option('display.width', 1000)

# 读取数据

df = pd.read_excel('data.xlsx', header=None, names=['name', 'user_id', 'age', 'gender', 'city', 'praise', 'date'], encoding='utf-8-sig', skipinitialspace=True)

print(df

私信小编001 获取神秘pandas大礼包!

这里以上期的网易云音乐用户数据为例。

R3my6v.jpg

R3my6v.jpg

01 行列操作

选择单列。可以直接用列名选择,也可以通过ix、iloc、loc方法进行选择行、列。

ix方法可以使用数值或者字符作为索引来选择行、列。

iloc则只能使用数值作为索引来选择行、列。

loc方法在选择列时只能使用字符索引。

# 返回pandas序列结构的类

print(df['age'])

print(df.age)

print(df.ix[:, 'age'])

print(df.loc[:, 'age'])

# 返回pandas数据框类

print(df[['age']])

print(df.iloc[:, 2:3])

输出结果。

fyUja2.jpg

fyUja2.jpg

Z3ERRr.jpg

Z3ERRr.jpg

选择多列。ix、iloc、loc方法都可使用。

只不过ix和loc方法,行索引是前后都包括的,而列索引则是前包后不包(与列表索引一致)。

iloc方法则和列表索引一致,前包后不包。

# 列索引前包后包

print(df.ix[0:5, 0:5])

print(df.loc[0:5, ('name', 'user_id', 'age', 'gender', 'city')])

# 列索引前包后不包

print(df.iloc[0:5, 0:5])

输出结果。

FBFVri.jpg

FBFVri.jpg

uQ3Efm.jpg

uQ3Efm.jpg

创建列。可以直接通过赋值完成,也可通过数据框的assign来完成赋值,不过后一种方法需要赋值给新表才能生效。

# 直接列赋值

df['adult'] = df['age'] // 18

print(df)

# 使用assign赋值

df = df.assign(adult=df['age'] // 18)

print(df)

两个方法的输出结果都一样。

ZBf63a.jpg

ZBf63a.jpg

删除列。使用数据框的方法drop。

# 删除单列

print(df.drop('date', axis=1))

# 删除多列

print(df.drop(['praise', 'date'], axis=1))

输出结果。

fAjiMr.jpg

fAjiMr.jpg

ZNV3y2.jpg

ZNV3y2.jpg

02 条件查询

单条件查询。使用比较运算符进行查询,如「== > < >= <= !=」。生成bool索引。

# 生成bool索引

print(df.age > 17)

# 返回符合条件的数据

print(df[df.age > 17])

输出结果,这里以年龄大于18岁为例。

I3UVvi.jpg

I3UVvi.jpg

ZfQJNj.jpg

ZfQJNj.jpg

多条件查询。无非就是加个逻辑运算符。如「& ~ |」,代表了与、非、或。

# 筛选年龄成年且性别为女性的用户

print(df[(df.age > 17) & (df.gender == 2)])

# 筛选评论点赞数不为0的用户

print(df[~(df.praise == 0)])

# 筛选地区在河南或湖南的用户

print(df[(df.city == 430100) | (df.city == 410100)])

输出结果。

3iIvae.jpg

3iIvae.jpg

vMVnmm.jpg

vMVnmm.jpg

FRzQ7r.jpg

FRzQ7r.jpg

当然Pandas还提供了更方便的条件查询方法,比如query、between、isin、str.contains(匹配开头)。

使用query进行条件查询。

# 筛选成年用户

print(df.query('age > 17'))

# 筛选地区在河南或湖南的用户

print(df.query('(city == 430100) | (city == 410100)'))

输出结果。

ZfQJNj.jpg

ZfQJNj.jpg

FRzQ7r.jpg

FRzQ7r.jpg

between方法,查询数据在某个范围的记录。

# 查询18到25岁的用户数据,inclusive为True意思是将边界包括在内

print(df[df['age'].between(18, 25, inclusive=True)])

输出结果。

VveY7v.jpg

VveY7v.jpg

对于字符串来说,可以使用isin方法进行查询。

# 查询在某个时间评论的用户情况

print(df[df['date'].isin(['2019-03-11 16:19:00', '2019-03-11 16:00:00'])])

输出结果。

eQRBza.jpg

eQRBza.jpg

03 横向连接

Pandas提供了merge方法来完成各种表的横向连接操作。其中包括内连接、外连接。

内连接,根据公共字段保留两表共有的信息。

# 表1

df1 = df.iloc[0:10, 0:2]

print(df1)

# 表2

df2 = df.iloc[0:10, 1:7]

print(df2)

两表数据如下。

Rj2ENv.jpg

Rj2ENv.jpg

jQVfiy.jpg

jQVfiy.jpg

两表横向连接代码如下。

# 公共字段名称一致时

print(df1.merge(df2, how='inner', on='user_id'))

# 公共字段名称不一致时

print(df1.merge(df2, how='inner', left_on='user_id', right_on='user_id'))

输出结果。

iIBn2y.jpg

iIBn2y.jpg

外连接包括左连接、右连接、全连接。

哪边连接,哪边的信息全保留,另一边的缺失信息会以NaN补全。

how的参数值分别为left、right、outer。

04 纵向连接

数据的纵向合并指的是将两张或多张表纵向拼接起来,使得原先两张或多张表的数据整合到一张表上。

# 表1

df1 = df.iloc[0:10, :]

print(df1)

# 表2

df2 = df.iloc[8:15, :]

print(df2)

两表数据如下。

EfIBZb.jpg

EfIBZb.jpg

Afaqqm.jpg

Afaqqm.jpg

pd.concat方法不仅可以完成纵向合并,还能完成横向合并。

当参数axis的值为0时,纵向合并。

当参数axis的值为1时,横向合并。

# ignore_index=True表示忽略两表原先的行索引,合并并重新排序索引,drop_duplicates()表示去重

print(pd.concat([df1, df2], ignore_index=True, axis=0).drop_duplicates())

输出结果。

NRjyQj.jpg

NRjyQj.jpg

05 排序

Pandas的排序方法有以下三种。

sort_values、sort_index、sortlevel。

第一个表示按值排序,第二个表示按索引排序,第三个表示按级别排序。

# 按用户年龄降序排序,last表示缺失值数据排在最后面(first)

print(df.sort_values('age', ascending=False, na_position='last'))

# 多个排序变量,这里以性别和年龄(有先后顺序)

print(df.sort_values(['gender', 'age'], ascending=False, na_position='last'))

输出结果。

JZny2u.jpg

JZny2u.jpg

IvmQFj.jpg

IvmQFj.jpg

06 分组汇总

groupby方法可以进行分组汇总。agg方法则可一次汇总多个统计量。

# 对性别分组,汇总点赞数,获取点赞数最大值

print(df.groupby('gender')[['praise']].max())

# 对性别和年龄分组,获取点赞数的平均值

print(df.groupby(['gender', 'age'])[['praise']].mean())

# 对性别分组,获取点赞数和年龄的平均值

print(df.groupby(['gender'])[['praise', 'age']].mean())

# 对性别分组,获取性别的计数值

print(df.groupby(['gender'])[['gender']].count())

# 多重索引

print(df.groupby(['gender', 'date'])['age', 'praise'].agg(['mean', 'max', 'min', 'count']))

输出结果,这里只展示计数的结果,也是平常用的比较多的。

vyeYfu.jpg

vyeYfu.jpg

通过上面的数值,就能绘制出用户性别分布情况的饼图。

07 赋值与条件赋值

# 将某个值替换

print(df.praise.replace(33, np.nan))

条件赋值。这里以性别列为例,将0,1,2替换为未知、男性、女性。

def transform(row):

"""

标识性别

"""

if row['gender'] == 1:

return ('男性')

elif row['gender'] == 2:

return ('女性')

else:

return ('未知')

# axis=1为列循环,axis=0为行循环

print(df.apply(transform, axis=1))

# 赋值到新列

print(df.assign(gender_c=df.apply(transform, axis=1)))

输出结果。

YnAfam.jpg

YnAfam.jpg

除了apply方法,还可以通过条件查询直接赋值。

df = df.copy()

df.loc[df.gender == 0, 'gender_c'] = '未知'

df.loc[df.gender == 1, 'gender_c'] = '男性'

df.loc[df.gender == 2, 'gender_c'] = '女性'

print(df)

输出结果,和上图一样。

/ 02 / 数据清洗

01 重复值处理

Pandas提供了查看和删除重复数据的方法,具体如下。

# 查看重复的数据

print(df[df.duplicated()])

# 删除重复的数据

print(df.drop_duplicates())

# 去除用户ID重复的所有记录

print(df.drop_duplicates('user_id'))

输出结果如下,分别对应查看,删除,特定列删除。

YniQJv.jpg

YniQJv.jpg

yQFJbm.jpg

yQFJbm.jpg

JzQJNb.jpg

JzQJNb.jpg

02 缺失值处理

Pandas提供了fillna方法用于替换缺失值数据。

# sum(col.isnull())表示当前列有多少缺失,col.size表示当前列总共有多少行数据

print(df.apply(lambda col: sum(col.isnull())/col.size))

首先查看各列的缺失情况。

RjUnaa.jpg

RjUnaa.jpg

填补缺失值数据,将昵称缺失值设置为未知。

# 填补缺失值

print(df.name.fillna('未知'))

输出结果。

z2IVJr.jpg

z2IVJr.jpg

还可以调用方法isnull产生缺失值指示变量。

# 默认的bool类型

print(df.name.isnull())

# 数值0、1型指示变量

print(df.name.isnull().apply(int))

输出结果。

eymY3e.jpg

eymY3e.jpg

6jy2qy.jpg

6jy2qy.jpg

03 数据分箱

分箱法包括等深分箱(每个分箱样本数量一致)和等宽分箱(每个分箱的取值范围一致)。

其中Pandas的qcut函数提供了分箱的实现方法,默认是实现等宽分箱。

# 等宽分箱

print(pd.cut(df.age, 5))

# 自定义标签

print(pd.cut(df.age, bins=5, labels=[10, 15, 20, 25, 30]))

这里以年龄为例,输出如下。

y6FRnu.jpg

y6FRnu.jpg

uAZZ7b.jpg

uAZZ7b.jpg

实现等深分箱,其中每个箱的宽度可能不一。

# 去除没有年龄数据的用户

df = df[df.age != 0]

# 输出等深度分2箱的分位数

print(df.age.quantile([0, 0.5, 1]))

# include_lowest=True表示包含边界的最小值

print(pd.cut(df.age, bins=df.age.quantile([0, 0.5, 1]), include_lowest=True))

输出结果。

qyay2q.jpg

qyay2q.jpg

/ 03 / 总结

有关Pandas的知识还很多,本次就到此为止。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值