python炼丹师_Python连载|Pandas终章

原标题:Python连载|Pandas终章

在数据挖掘中,我们常需要对数据进行清洗或者转换,以便于认识数据特征,掌握数据间的关系。下面将重点介绍如何使用Pandas来解决数据挖掘中常见的问题。

c555eaedb56fba6e19515b76c7b783a4.png

1 Pandas缺失数据

数据缺失是数据挖掘中最为常见的问题,下面将讲解如何利用pandas进行缺失值处理。

1.1 查找缺失值

对于数值数据,pandas使用浮点值NaN表示缺失数据。我们可以通过isnull和notnull来检测缺失值:

data = pd . DataFrame ({ 'A' :[ 1 , 6 , np . nan , 4 , np . nan ], 'B' :[ 2 , np . nan , 3 , 9 , 5 ], 'C' :[ 5 , 7 , 9 , 8 , 4 ]})

# 通过isnull和notnull函数检查缺失值

print ( data . isnull ) # True表示NaN

print ( data . notnull ) # False表示NaN

输出结果:

# data.isnull

A B C

0 False False False

1 False True False

2 True False False

3 False False False

4 True False False

# data.notnull

A B C

0 True True True

1 True False True

2 False True True

3 True True True

4 False True True

当然,在实际应用中,我们可以通过以下方法来得出每一列(行)的缺失值个数

print ( data . isnull . sum ) # 统计每一列有多少个缺失值

print ( data . isnull . sum ( axis = 1 )) # 统计每一行有多少个缺失值

输出结果:

# data.isnull.sum

A 2

B 1

C 0

dtype : int64

# data.isnull.sum(axis=1)

0 0

1 1

2 1

3 0

4 1

dtype : int64

除此之外,还可以查找出具有缺失值的行的index

print ( data . index [ data . isnull . sum ( axis = 1 )> 0 ])

输出结果:

Int64Index ([ 1 , 2 , 4 ], dtype = 'int64' )1.2 删除缺失值

通过dropna函数可对缺失值进行删除,具体参数说明如下

dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)

axis: 默认为0,删除包含缺失值的行;当为1时,删除包含缺失值的列

how: 默认为any,只要有缺失值出现,就删除;为all时,所有的值都缺失才删除

thresh: axis中至少有thresh个非缺失值,否则删除

subset: 在哪些列中查看是否有缺失值

inplace: 是否在原数据上操作

删除存在空值的行,how默认情况下为any

data . dropna

# 结果为:

A B C

0 1.0 2.0 5

3 4.0 9.0 8

同样,可以删除存在缺失值的列

data . dropna ( axis = 1 ) # 删除存在缺失值的列

# 结果为:

C

0 5

1 7

2 9

3 8

4 4

当how参数设置为all时,只有列中的数据都为空时才删除

data . dropna ( axis = 1 , how = 'all' )

# 结果为:

A B C

0 1.0 2.0 5

1 6.0 NaN 7

2 NaN 3.0 9

3 4.0 9.0 8

4 NaN 5.0 4

也可根据实际需求来设置thresh参数

print ( data . dropna ( axis = 1 , thresh = 4 )) # 每一列的非空值个数>=4,否则删除

data . dropna ( axis = 1 , thresh = 4 , inplace = True ) # 在原数据上操作

print ( data )

输出结果

# data.dropna(axis = 1,thresh = 4)

B C

0 2.0 5

1 NaN 7

2 3.0 9

3 9.0 8

4 5.0 4

# data

B C

0 2.0 5

1 NaN 7

2 3.0 9

3 9.0 8

4 5.0 41.3 缺失值填补

除了对缺失值进行删除外,我们还可以使用fillna函数来对缺数值进行填补。具体参数说明如下

fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)

value:用于填充缺失值的标量值或字典对象

method:插值方式。如果函数调用时未指定其他参数的话,默认为‘ffill’

axis:待填充的轴,默认为0

inplace:是否在原数据上操作

limit:对于前向和后向填充,可以连续填充的最大数量

可以使用0值或者均值来填补缺失值

data = pd . DataFrame ({ 'A' :[ 1 , 6 , np . nan , 4 , np . nan ], 'B' :[ 2 , np . nan , 3 , 9 , 5 ], 'C' :[ 5 , 7 , 9 , 8 , 4 ]})

print ( data )

print ( data . fillna ( 0 )) # 使用0来填充缺少值

print ( data . fillna ( data . mean )) # 用均值来填补缺失值

输出结果:

# data

A B C

0 1.0 2.0 5

1 6.0 NaN 7

2 NaN 3.0 9

3 4.0 9.0 8

4 NaN 5.0 4

# data.fillna(0)

A B C

0 1.0 2.0 5

1 6.0 0.0 7

2 0.0 3.0 9

3 4.0 9.0 8

4 0.0 5.0 4

# data.fillna(data.mean)

A B C

0 1.000000 2.00 5

1 6.000000 4.75 7

3 4.000000 9.00 8

此外,还可以传入字典,对不同列的缺失值进行填补

print ( data . fillna ( value = { 'A' : 0.5 , 'B' : 0.4 })) # 用0.5来填补A列的空值,0.4来填补B列的空值

# 结果为:

A B C

0 1.0 2.0 5

1 6.0 0.4 7

2 0.5 3.0 9

3 4.0 9.0 8

4 0.5 5.0 4

也可以通过向前填充和向后填充来对缺失数据进行填补

print ( data . fillna ( method = 'pad' )) # 将缺失值按照前面一个值进行填充。pad/fill 填充方法向前

print ( data . fillna ( method = 'bfill' )) # 将缺失值按照后面一个值进行填充。bfill/backfill 填充方法向后

print ( data . fillna ( axis = 1 , method = 'bfill' )) # 修改轴方向,用后面列的值来填充

输出结果

# data.fillna(method='pad')

A B C

0 1.0 2.0 5

1 6.0 2.0 7

2 6.0 3.0 9

3 4.0 9.0 8

4 4.0 5.0 4

# data.fillna(method='bfill')

A B C

0 1.0 2.0 5

1 6.0 3.0 7

2 4.0 3.0 9

3 4.0 9.0 8

4 NaN 5.0 4

# data.fillna(axis=1,method='bfill')

A B C

0 1.0 2.0 5.0

1 6.0 7.0 7.0

2 3.0 3.0 9.0

3 4.0 9.0 8.0

4 5.0 5.0 4.0

limit参数限制填充个数

df = pd . DataFrame ({ 'A' :[ 1 , 6 , np . nan , np . nan , np . nan ], 'B' :[ 2 , np . nan , 3 , 9 , 5 ], 'C' :[ 5 , 7 , 9 , 8 , 4 ]})

print ( df )

print ( '==================' )

print ( df . fillna ( method = 'pad' , limit = 1 )) # 限制向前填充个数为1

输出结果

A B C

0 1.0 2.0 5

1 6.0 NaN 7

2 NaN 3.0 9

3 NaN 9.0 8

4 NaN 5.0 4

==================

A B C

0 1.0 2.0 5

1 6.0 2.0 7

2 6.0 3.0 9

3 NaN 9.0 8

4 NaN 5.0 41.4 数据替换

pandas中还可使用replace来进行数据替换

replace(self,to_replace = None,value = None,inplace = False,limit = None,regex = False,method ='pad' )

将to_replace替换成value

to_replace:被替换的值

value:用于替换的值,可以是标量,字典,列表等

inplace:是否在原数据上操作

limit:向前或向后填充的最大间隔

下面举例来介绍replace的使用方法

df = pd . DataFrame ({ 'one' :[ 10 , 20 , 30 , 40 , 50 ],

'two' :[ 1000 , 0 , 30 , 40 , 50 ]})

print ( df . replace ( 0 , 100 )) # 将0替换成100

# 结果为:

one two

0 10 1000

1 20 100

2 30 30

3 40 40

4 50 50

也可以传入字典、列表来对数值进行替换

print ( df . replace ({ 0 : 666 , 1000 : 888 })) # 用字典形式来替换多个数值,字典的key为原值,value为替换后的值

print ( df . replace ([ 0 , 50 ],[ 666 , 5 ])) # 用列表的形式替换多个数值,传入两个列表,第一个列表中的值为原值,第二列表中的值为替换值

输出结果

# df.replace({0:666,1000:888})

one two

0 10 888

1 20 666

2 30 30

3 40 40

4 50 50

# df.replace([0,50],[666,5])

one two

0 10 1000

1 20 666

2 30 30

3 40 40

4 5 5

使用正则表达式来替换,将所有大写英文替换成N。在使用正则表达式替换时,必须将regex设置为True

print ( df . replace ( r '[A-Z]' , 'N' , regex = True ))

# 结果为:

one two

0 10 1000

1 20 N

2 30 30

3 40 40

4 N N2. 长宽表转换

长格式数据:每一行数据记录的是ID的一个属性,形式为key:value

宽格式数据:每一行数据为是一条完整的记录,记录着ID的各种属性

长格式数据和宽格式数据的形式如下

302201519a4ed5b84fa0d0b20ad025ae.png

2.1 长表转宽表

使用pivot可将长格式数据转换成宽格式数据,参数columns是长格式数据中的key键对应的列名;参数values是长格式数据中的value对应的列。

data = pd . DataFrame ({

'id' :[ 'id1' ]* 3 + [ 'id2' ]* 3 + [ 'id3' ]* 3 ,

'Introduction' :[ 'int1' , 'int2' , 'int3' ]* 3 ,

'Message' : [ 'abc' , 'def' , 'hhh' , '123' , '456' , '789' , 'zxc' , 'qwe' , 'asd' ]

})

print ( data ) # 长表

data_p = data . pivot ( index = 'id' , columns = 'Introduction' , values = 'Message' )

print ( data_p ) # 转成宽表

输出结果

# data

id Introduction Message

0 id1 int1 abc

1 id1 int2 def

2 id1 int3 hhh

3 id2 int1 123

4 id2 int2 456

5 id2 int3 789

6 id3 int1 zxc

7 id3 int2 qwe

8 id3 int3 asd

# data_p

Introduction int1 int2 int3

id

id1 abc def hhh

id2 123 456 789

id3 zxc qwe asd

此外,也可以使用pivot_table将长表格转换成宽表格,但有一点需要注意,由于pivot_table函数对values进行计算(求和、平均等),所以values要为数值型数据

data2 = pd . DataFrame ({

'Company' :[ 'C1' ]* 3 + [ 'C2' ]* 3 + [ 'C3' ]* 3 + [ 'C4' ]* 3 ,

'Year' :[ '2017' , '2018' , '2019' ]* 4 ,

'Sale' :[ 2000 , 1500 , 3000 , 3500 ]* 3

})

print ( data2 )

data2_pt = data2 . pivot_table ( index = 'Company' , columns = 'Year' , values = 'Sale' )

print ( data2_pt )

输出结果

# data2

Company Year Sale

0 C1 2017 2000

1 C1 2018 1500

2 C1 2019 3000

3 C2 2017 3500

4 C2 2018 2000

5 C2 2019 1500

6 C3 2017 3000

7 C3 2018 3500

8 C3 2019 2000

9 C4 2017 1500

10 C4 2018 3000

11 C4 2019 3500

# data2_pt

Year 2017 2018 2019

Company

C1 2000 1500 3000

C2 3500 2000 1500

C3 3000 3500 2000

C4 1500 3000 35002.2 宽表转长表

在pandas中,只需使用melt函数,即可将宽表转成长表

wide_data = pd . DataFrame ({

'id' :[ 'id1' , 'id2' , 'id3' ],

'name' :[ '小李' , '小何' , '小周' ],

'sex' :[ 'male' , 'male' , 'female' ],

'score' :[ 89 , 60 , 76 ]

})

print ( wide_data )

wide_data = wide_data . melt ( id_vars = 'id' ,

var_name = 'Introduction' , value_name = 'Message' )

print ( wide_data )

输出结果

# 转换前

id name sex score

0 id1 小李 male 89

1 id2 小何 male 60

2 id3 小周 female 76

# 转换后

id Introduction Message

0 id1 name 小李

1 id2 name 小何

2 id3 name 小周

3 id1 sex male

4 id2 sex male

5 id3 sex female

6 id1 score 89

7 id2 score 60

8 id3 score 763. pandas0.25新功能 3.1 Groupby的命名聚合

可以直接为指定的聚合输出列命名

# 创建样例数据

data1 = pd . DataFrame ({ '列1' :[ 'aa' , 'bb' , 'aa' , 'bb' ],

'列2' :[ 8.1 , 6.0 , 10.5 , 34.0 ],

'列3' :[ 7.9 , 7.5 , 9.9 , 50.0 ]})

print ( data1 )

列 1 列 2 列 3

0 aa 8.1 7.9

1 bb 6.0 7.5

2 aa 10.5 9.9

3 bb 34.0 50.0

在Pandas0.25中,命名聚合支持中文变量名

data1 . groupby ( '列1' ). agg (

最低 = pd . NamedAgg ( column = '列2' , aggfunc = 'min' ),

最高 = pd . NamedAgg ( column = '列2' , aggfunc = 'max' ),

平均 = pd . NamedAgg ( column = '列3' , aggfunc = np . mean ),

总和 = pd . NamedAgg ( column = '列3' , aggfunc = np . sum )

)

输出结果:

最低 最高 平均 总和

列 1

aa 8.1 10.5 8.90 17.8

bb 6.0 34.0 28.75 57.53.2 Groupby聚合支持多个lambda函数

以 list 方式向 agg 函数传递多个 lambda 函数

data1 . groupby ( '列1' ). agg ([

lambda x : x . iloc [ 0 ] - x . iloc [ 1 ],

lambda x : x . iloc [ 0 ] + x . iloc [ 1 ]

])

输出结果:

列 2 列 3

< lambda_0 > < lambda_1 > < lambda_0 > < lambda_1 >

列 1

aa - 2.4 18.6 - 2.0 17.8

bb - 28.0 40.0 - 42.5 57.53.3 explode方法

Series 与 DataFrame 增加了 explode 方法,将list形式的值转换为单独的行

df = pd . DataFrame ([{ '变量1' : 'a,b,c' , '变量2' : 1 },

{ '变量1' : 'd,e,f' , '变量2' : 2 }])

var_list = df [ '变量1' ]. str . split ( ',' )

var_explode = df [ '变量1' ]. str . split ( ',' ). explode

print ( var_list )

print ( var_explode )

输出结果:

# var_list

0 [ a , b , c ]

1 [ d , e , f ]

Name : 变量 1 , dtype : object

# var_explode

0 a

0 b

0 c

1 d

1 e

1 f

Name : 变量 1 , dtype : object3.4 Query支持列名空格

data = [

{ '姓 名' : '张三' , '城 市' : '北京' , '年 龄' : 18 },

{ '姓 名' : '李四' , '城 市' : '上海' , '年 龄' : 19 , '爱 好' : '打游戏' },

{ '姓 名' : '王五' , '城 市' : '广州' , '年 龄' : 20 , '财务状况' : '优' }

]

data = pd . DataFrame ( data )

上方示例数据的列名是有空格的,只需用反引号(`)括住列名,就可以进行查询了

data . query ( '`年 龄` < 19' )

姓 名 城 市 年 龄 爱 好 财务状况

0 张三 北京 18 NaN NaN

至此,本次分享已结束

如果你喜欢的话,可以转发或者点个“在看”支持一下~

点击原文链接,可以下载《Python工具代码速查手册》,可以点个star支持一下哦~简介:浩彬老撕 好玩的数据炼丹师, 曾经的IBM数据挖掘攻城狮, 还没开始就过气数据科学界的段子手, 致力于数据科学知识分享,不定期送书活动

责任编辑:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值