Python 全栈 400 之Pandas数据分析练习

本文介绍了Pandas在数据分析中的常用操作,包括读取URL路径文件、设置分隔符、处理空值、分块读取大数据、随机抽样、创建和操作Series、DataFrame的增删改查、数据清洗、特征工程、数据透视及连接方法。通过实例展示了Pandas的强大功能,如灵活的数据访问、分箱、编码、时间序列分析等。
摘要由CSDN通过智能技术生成
288 Pandas 读取 URL 路径的文件

数据输入路径,可以是文件路径,也可以是 URL,或者实现 read 方法的任意对象。

如下经典的数据集 iris,直接通过 URL 获取。

In [160]: pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data')
Out[160]:
     5.1  3.5  1.4  0.2     Iris-setosa
0    4.9  3.0  1.4  0.2     Iris-setosa
1    4.7  3.2  1.3  0.2     Iris-setosa
2    4.6  3.1  1.5  0.2     Iris-setosa
3    5.0  3.6  1.4  0.2     Iris-setosa
4    5.4  3.9  1.7  0.4     Iris-setosa
..   ...  ...  ...  ...             ...
144  6.7  3.0  5.2  2.3  Iris-virginica
145  6.3  2.5  5.0  1.9  Iris-virginica
146  6.5  3.0  5.2  2.0  Iris-virginica
147  6.2  3.4  5.4  2.3  Iris-virginica
148  5.9  3.0  5.1  1.8  Iris-virginica

[149 rows x 5 columns]
289 Pandas 读取文件之 sep 分隔符

默认为逗号,注意:如果分割字符长度大于1,且不是 \s+, 启动 Python 引擎解析。

举例:test.csv 文件分割符为 \t, 如果使用 sep 默认的逗号分隔符,读入后的数据混为一体。

# 创建并保存数据
In [1]: d = {'id':[1,2],'name':['gz','lh'],'age':[10,12]}
In [2]: df = pd.DataFrame(d)
In [3]: df.to_csv('test.csv',sep='\t')

#读取数据
In [4]: df = pd.read_csv('test.csv')
In [5]: df
Out[5]:
  \tid\tname\tage
0    0\t1\tgz\t10
1    1\t2\tlh\t12

sep 必须设置为 '\t',数据分割才会正常。

In [6]: df = pd.read_csv('test.csv',sep='\t')
In [6]: df
Out[6]:
   Unnamed: 0  id name  age
0           0   1   gz   10
1           1   2   lh   12
290 Pandas 读取之列选择属性

参数用于选取数据文件的哪些列到 DataFrame 中,如下所示,只想使用源数据文件的 id 和 age 两列,那么可以为 usecols 参数赋值为 ['id','name']:

In [1]: df = pd.read_csv('test.csv',delim_whitespace=True,usecols=['id','name'])

In [2]: df
Out[2]:
   id name
0   1   gz
1   2   lh
291 Pandas 读取之空值处理

参数可以配置哪些值需要处理成Na/NaN, 类型为字典,键指明哪一列,值为看做 Na/NaN 的字符。

假设我们的数据文件如下,date 列中有一个 # 值,我们想把它处理成 NaN 值。

In [1]: d = {'id':[1,2],'name':['gz','lh'],'age':[10,12],'date':['2020-03-10','#']}
In [2]: df = pd.DataFrame(d)
In [3]: df.to_csv('test_date.csv',sep=' ',index=False)

In [4]: df = pd.read_csv('test_date.csv',sep='\s+')    

可以使用,na_values 实现:

In [37]:  df = pd.read_csv('test_date.csv',sep='\s+',na_values=['#'])

In [38]: df
Out[38]:
   id name  age        date
0   1   gz   10  2020-03-10
1   2   lh   12         NaN

keepdefaultna 是和 navalues 搭配的,如果前者为 True,则 navalues 被解析为 Na/NaN 的字符除了用户设置外,还包括默认值。

292 Pandas 之分块读入数据

iterator 取值 boolean, 默认为 False, 返回一个 TextFileReader 对象,以便逐块处理文件。

这个在文件很大时,内存无法容纳所有数据文件,此时分批读入,依次处理。

具体操作演示如下,我们的文件数据域一共有 2 行。

先读入一行,get_chunk 设置为 1 表示一次读入一行

In [64]: chunk = pd.read_csv('test.csv',sep='\s+',iterator=True)

In [65]: chunk.get_chunk(1)
Out[65]:
   id name  age
0   1   gz   10

再读入下一行,

In [66]: chunk.get_chunk(1)
Out[66]:
   id name  age
1   2   lh   12

此时已到文件末尾,再次读入会报异常,

In [108]: chunk.get_chunk(1)  

StopIteration
293 Pandas 之随机选取一部分数据案例

对于动辄就几十或几百个 G 的数据,在读取的这么大数据的时候,我们有没有办法随机选取一小部分数据,然后读入内存,快速了解数据和开展 EDA ?

使用 Pandas 的 skiprows 和 概率知识,就能做到。

下面解释具体怎么做。

如下所示,读取某 100 G 大小的 big_data.csv 数据

1) 使用 skiprows 参数,

2) x > 0 确保首行读入,

3) np.random.rand() > 0.01 表示 99% 的数据都会被随机过滤掉

言外之意,只有全部数据的 1% 才有机会选入内存中。

import pandas as pd
import numpy as np

df = pd.read_csv("big_data.csv", 
skiprows = 
lambda x: x>0 and np.random.rand() > 0.01)

print("The shape of the df is {}. 
It has been reduced 100 times!".format(df.shape))

使用这种方法,读取的数据量迅速缩减到原来的 1% ,对于迅速展开数据分析有一定的帮助。

294 Pandas 之一维数组 Series

Series 是 pandas 两大数据结构中(DataFrame,Series) 的一种,先从 Series 的定义说起,Series 是一种类似于一维数组的对象,它由一组数据域以及一组与之相关联的数据标签和索引组成。

Series 对象也是一个 NumPy 的数组,因此 NumPy 的数组处理函数可以直接对 Series 进行处理。

与此同时,Series 除了可以使用位置索引作为下标存取元素之外,还可以使用标签下标存取元素,这一点和字典相似,每个 Series 对象都由两个数组组成:

  1. index:它是从 NumPy 数组继承的 Index 对象,保存标签信息。
  2. values:保存值的 NumPy 数组。

接下来,分别介绍 Series 内元素的增加、删除、修改、访问。

295 Pandas 之创建 Series

Series 的标准构造函数, 列举常用的几个参数:

Series(data=None, index=None, dtype=None, name=None)

其中,data 为数据部分,index 为标签部分,省略下默认为自增整数索引,dtype 为 str, numpy.dtype, or ExtensionDtype。

创建一个 series,如下:

In [85]: ps = pd.Series(data=[-3,2,1],index=['a','f','b'],dtype=np.float32)     

In [86]: ps                                                                     
Out[86]: 
a   -3.0
f    2.0
b    1.0
dtype: float32
296 Series 之增加元素

在 ps 基础上增加一个元素,使用 append,如下:

In [112]: ps.append(pd.Series(data=[-8.0],index=['f']))                         
Out[112]: 
a    4.0
f    2.0
b    1.0
f   -8.0
dtype: float64

可以看到,Pandas 允许包含重复的标签

In [114]: psn = ps.append(pd.Series(data=[-8.0],index=['f']))                   

In [115]: psn                                                                   
Out[115]: 
a    4.0
f    2.0
b    1.0
f   -8.0
dtype: float64

In [116]: psn['f']                                                              
Out[116]: 
f    2.0
f   -8.0
dtype: float64

利用标签访问元素,返回所有带标签的数据。

297 Series之删除元素

使用 drop 删除指定标签的数据,如下:

In [119]: ps                                                                    
Out[119]: 
a    4.0
f    2.0
b    1.0
dtype: float32

In [120]: psd = ps.drop('f')                                                    
In [121]: psd                                                                  
Out[121]: 
a    4.0
b    1.0
dtype: float32

注意不管是 append 操作,还是 drop 操作,都是发生在原数据的副本上,不是原数据上。

298 Series 之修改元素

通过标签修改对应数据,如下所示:

In [123]: psn                                                                   
Out[123]: 
a    4.0
f    2.0
b    1.0
f   -8.0
dtype: float64

In [124]: psn['f'] = 10.0                                                       
In [125]: psn                                                                   
Out[125]: 
a     4.0
f    10.0
b     1.0
f    10.0
dtype: float64

标签相同的数据,都会被修改。

299 Series 之访问元素

访问元素,Pandas 提供两种方法,

  • 一种通过默认的整数索引,在 Series 对象未被显示的指定 label 时,都是通过索引访问;
  • 另一种方式是通过标签访问。
In [126]: ps                                                                    
Out[126]: 
a    4.0
f    2.0
b    1.0
dtype: float32

In [128]: ps[2] # 索引访问                              
Out[128]: 1.0

In [127]: ps['b']  # 标签访问                                                             
Out[127]: 1.0
300 Pandas 之二维数组 DataFrame

DataFrame, Pandas 两个重要数据结构中的另一个,可以看做是 Series 的容器。

DataFrame 同时具有行、列标签,是二维的数组,行方向轴 axis 为 0, 列方向 axis 为 1,如下:

axis : {0 or 'index', 1 or 'columns'}

创建 DataFrame

DataFrame 构造函数如下:

DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)

参数意义与 Series 相似,不再赘述。

创建 DataFrame 的常用方法:

In [134]: df = pd.DataFrame([['gz',4.0,'2019-01-01'],['lg',1.2,'2019-06-01']],index = ['a','f'], columns = ['nm', 'y','da'])                          

In [135]: df                                                                    
Out[135]: 
   nm    y          da
a  gz  4.0  2019-01-01
f  lg  1.2  2019-06-01

也可以通过字典传入,得到一样的 DataFrame,如下:

In [136]: df2 = pd.DataFrame({'nm':['gz','lg'],'y':[4.0,1.2], 'da':['2019-01-01', '2019-06-01']},index = ['a','f'])                                   
In [137]: df2                                                                   
Out[137]: 
   nm    y          da
a  gz  4.0  2019-01-01
f  lg  1.2  2019-06-01
301 DataFrame 之增加数据

通过增加一个 Series,扩充到 DataFrame 中,如下所示:

In [143]: dfn = df.append(pd.Series(data=['zx',3.6,'2019-05-01'],index=['nm','y','da'],name='b'))                                                     
In [144]: dfn                                                                   
Out[144]: 
   nm    y          da
a  gz  4.0  2019-01-01
f  lg  1.2  2019-06-01
b  zx  3.6  2019-05-01

Series 的 index 与 DataFrame 的 column 对齐,name 与 DataFrame 的 index 对齐。

302 DataFrame 之删除数据

与 Series 删除类似,也是使用 drop 删除指定索引或标签的数据。如下,注意删除仍然是在 dfn 的副本上进行,像下面这样删除对 dfn 没有任何影响。

In [145]: dfn.drop('b')                                                         
Out[145]: 
   nm    y          da
a  gz  4.0  2019-01-01
f  lg  1.2  2019-06-01

如果要删除某列,需要设定 axis 为 1, 如下所示:

In [147]: dfn.drop('y',axis=1)                                                  
Out[147]: 
   nm          da
a  gz  2019-01-01
f  lg  2019-06-01
b  zx  2019-05-01
303 DataFrame 之修改数据

修改依然是先通过索引或标签定位到数据,然后修改,如下所示:

In [151]: dfn.loc['a','da']='2019-04-01'                                        
In [152]: dfn                                                                   
Out[1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值