《基于Python的大数据分析基础及实战》第二章

第二章

👉个人信息
  • kwd:info
  • kwd:info
  • kwd:info
🞸🞸🞸🞸🞸🞸🞸🞸♥🞸🞸🞸🞸🞸🞸🞸🞸

ipynb等文件下载:https://wwm.lanzouf.com/iklXf023qeef

对数据进行分析首先得对数据进行处理,本章主要介绍Pγthon在数据处理方面的常用方法与技巧,以及Anaconda的安装。毕竟Anaconda 和
Jupγter notebook 已成为款据分析的标准坏境。

本章开始进入Python革之据分析工具的介绍。革之据分析一般都妥周到Numpγ 、Scipγ 和Pandas三个包。Numpγ是Pγthon的主义值计算扩在包,主妥用来处理矩阵,宅的运算效率比到家史高效。Scipy是基于Numpy 的科学计算包,包括线性代狄、统计等工具。Pandas是基于Numpγ的数据分析工具,能方便地操作大型数据集。

2.1Anaconda简介

Anaconda 是Python 的一个开源发行版本,主要面向科学计算,是一个非常好用且最省心的Python 学习工具。对于学习Pyt hon 的“小白" 来说,安装第三方库就很折腾人,但用了Anaconda 就方便多了,它预装了很多我们用的到或用不到的第三方库,而且相比于Python 用pip install 命令安装库也更方便。Anaconda 中增加了conda install 命令来安装第三方库,方法与pip install 命令一样。当用户熟悉了Anaconda 以后会发现,使用conda install 命令会比使用pip install 命令更方便一些。比如大家经常烦恼的lxml 包的问题, 在Windows 下使用pip install 命令是无法顺利安装的,而使用conda 命令则可以。

1. 代码提示

代码提示是开发工具必备的功能。当用户需要Spyder 给出代码提示时,只
需要输入函数名的前几个字母,再按下Ta b 键,即可得到IDE 的代码提示。

2. 变量浏览

变量是代码执行过程中暂留在内存中的数据,可以通过Spy der 对变量承载
的数据进行查看,方便用户对数据进行处理。

3. 图形查看

绘图是进行数据分析必备的技能之一。一款好的工具,必须具备图形绘制
的功能, Spyder 窗体还集成了绘图功能

2.2Numpy简介

Numpy 的数据结构是n 维的数组对象,叫做ndarray 。在前面的章节中,我
们己经了解到Python 的列表也能表示数组,但随着列表数据的增加,效率会
降低。

本书使用 Anaconda ,无须另外安装 Numpy ,但因为它属于 Python 的第三方工具,所以每次使用前必须在代码中载入 导入(载入)命令如下:

import numpy as np
data1=[1,2,3,4,5] 
array1=np.array(data1)
array1

array([1, 2, 3, 4, 5])

创建数组(矩阵)使用Numpy中的array函数,新手要记住加"np."。上面的代码已经将系统自带的列表(list)转换成Numpy中的数组。把一个列表作为元素的嵌套列表可以用np.转换为一个多维数组,也就是我们所说的矩阵。

具体代码如下:

data2=[[1,3,4], [2,5, 6]] 
array2=np.array (data2) 
array2
array([[1, 3, 4],
       [2, 5, 6]])

2.3关于Pandas

2.3.1什么是Pandas

Pandas 是Python 的一个数据分析包。最初由AQR Capital Management 于
2008 年4 月开发,并于2009 年年底开源面市。目前由专注于Python 数据包开
发的PyData 开发团队继续开发和维护,属于PyData 项目的一部分。Pandas 最
初是被作为金融数据分析工具而开发出来的,因此, Pandas 为时间序列分析提
供了很好的支持。Pandas 的名称来自于面板数据( Panel Data )和Python 数据
分析( Data Analysis ) 。Panel Data 是经济学中关于多维数据集的一个术语,在
Pandas 中也提供了Panel Data 的数据类型。

2.3.2Pandas中的数据结构

Pandas 中除了Panel 数据结构,还引入了两种新的数据结构一- Series 和
DataFrame ,这两种数据结构都建立在NumPy 的基础之上。

( 1 ) Series :一维数组系列,也称序列,与Numpy 中的一维array 类似。
二者与Python 基本的数据结构list 也很相近。

( 2 ) DataFrame :二维的表格型数据结构。可以将DataFrame 理解为Series
的容器。以下的内容主要以DataFrame 为主。

( 3) Panel :三维数组,可以理解为DataFrame 的容器。

2.4数据准备

2.4.1数据类型

Python 常用的3 种数据类型为: Logical 、Numeric 、Character 。

1. Logical

Logical 又叫布尔型,只有两种取值: 0 和1 ,或者真和假( True 和False ) 。
逻辑运算符有:& (与,两个逻辑型数据中,有一个为假,则结果为假〉,
|(或,两个逻辑型数据中,有一个为真,则结果为真) , not (非,取反〉。

表2-1 运算规则
运算符注释运算规则
&两个逻辑型数据中,其中一个数据为假, 则结果为假
|两个逻辑型数据中,其中一个数据为真, 则结果为真
not取相反值,非真的逻辑型数据为假,非假的逻辑型数据为真
2. Numeric

数值运算符有:+、-、*、/。

3. Character

宇符型数据一般使用单引号(")或者双引号( “” )包起来。
Python 数据类型变量命名规则如下:

( 1 )变量名可以由a~z 、A~Z、数字、下划线组成, 首字母不能是数字和
下划线;

( 2 )大小写敏感,即区分大小写;

( 3 )变量名不能为Python 中的保留字,如and 、continue 、lambda 、
or 等。

2.4.2数据结构

数据结构是指相互之间存在的一种或多种特定关系的数据类型的集合。
Pandas 中主要有Series (系列)和Dataframe (数据框)两种数据结构。

1. Series

Series (系列,也称序列)用于存储一行或 列的数据,以及与之相关的索引的集合 。使用方法如下:

Ser es ([数据 ,数据 ... ],index=[索引 ,索引 2, ...])

例如:

from pandas import Series 
X = Series (['a',2 ,'螃蟹'], index= [1,2,3] )
X
1     a
2     2
3    螃蟹
dtype: object

一个系列允许存放多种数据类型 ,索引 Index )也可 以省略,可以通过位
置或者索引访问数据,如X[3],返回 螃蟹。
Series index 如果省略,索引号默认从 开始,也可以指定索引名 。为了
方便后面的使用和说明,此处定义可以省略的 index ,也就是默认的索引号从
开始计数,赋值给定的 index ,我们称为索引名,有时也称为行标签。

在Spyder 中写入如下代码:

from pandas import Series 
A=Series([1,2,3]) 
print(A) 
0    1
1    2
2    3
dtype: int64
from pandas import Series 
A=Series(
    [1,2,3],
    index=[1,2,3]
)
print(A)
1    1
2    2
3    3
dtype: int64
from pandas import Series 
A=Series([1,2,3],index= [ 'A','B', 'c']) 
print (A) 
A    1
B    2
c    3
dtype: int64
2. DataFrame

2.4.3数据导入

数据存在的形式多种多样,有文件( csv、Excel、txt )和数据库CMySQL 、
Access 、SQL Server )等形式。在Pandas 中,常用的载入函数是read_csv,除此
之外还有read excel 和read table 。read table 函数可以读取txt 文件。若是服务
器相关的部署,则还会用到read_sql 函数,直接访问数据库,但它必须配合
MySQL 相关的包。

  1. 导入txt文件

read table 函数用于导入txt 文件。其命令格式如下:

read table(file, names =[歹u名1 ,列名2, ... J , sep="", ...)

其中:

  • 目怆为文件路径与文件名;
  • names 为列名,默认为文件中的第一行作为列名:
  • sep 为分隔符,默认为空。
【例 2-1】读取(导入) txt 文件
from pandas import read_table
df = read_table(r'rz.txt',sep=" ")
df.head()
学号\t班级\t姓名\t性别\t英语\t体育\t军训\t数分\t高代\t解几
02308024241\t23080242\t成龙\t男\t76\t78\t77\t40\t2...
12308024244\t23080242\t周怡\t女\t66\t91\t75\t47\t4...
22308024251\t23080242\t张波\t男\t85\t81\t75\t45\t4...
32308024249\t23080242\t朱浩\t男\t65\t50\t80\t72\t6...
42308024219\t23080242\t封印\t女\t73\t88\t92\t61\t4...
2. 导入csv文件

csv (Comma-Separated Values )一般称为逗号分隔值,有时也称为字符分隔
因为分隔字符也可以不是逗号,其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含有必须像二进制数字那
样被解读的数据。csv 文件由任意数目的记录组成, 记录间以某种换行符分
隔; 每条记录由字段组成, 字段间的分隔符是其他字符或字符串,最常见的是
逗号或制表符。通常, 所有记录都有完全相同的字段序列。通常都是纯文本文
件。csv 文件格式常见于手机通讯录,可以使用Excel 打开。

read_csv 函数可以导入csv 文件。其命令格式如下:

read_csv(file , names =[列名1 ,列名2, .. ] , sep="",)

其中:

  • file 为文件路径与文件名;
  • names 为列名,默认为文件中的第一行作为列名;
  • sep 为分隔符, 默认为空, 表示默认导入为一列。
【例2-2】读取(导入) csv文件。
示例代码如下:
from pandas import read_csv
df = read_csv(r'rz.csv',sep ="," )
df
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
5230802420123080242迟培605089717671
6230802434723080243李华676184616578
7230802430723080243陈田767986694069
8230802432623080243余皓666785656171
9230802432023080243李嘉62作弊90606777
10230802434223080243李上初769084606660
11230802431023080243郭窦796784646479
12230802443523080244姜毅涛7771缺考617376
13230802443223080244赵宇747488687071
14230802444623080244周路768077617480
15230802442123080244林建祥727281639075
16230802443323080244李大强797677787070
17230802442823080244李侧通649691696077
18230802440223080244王慧737493707175
19230802442223080244李晓亮856085727283
20230802420123080242迟培605089717671
3. 导入Excel文件

read_excel 函数可以导入Excel 文件。其命令格式如下:

read_excel (file,sheetname,header=0)

其中:

  • file 为文件路径与文件名:
  • sheetname 为sheet 的名称,如sheetl;
  • header 为列名,默认为0 (只接收布尔型数据0 和1 ),一般以文件的
    第一行作为列名。
【例2-3】 读取(导入)Excel文件
实例代码如下:
from pandas import read_excel
df =read_excel(r'i_nuc.xls',sheet_name='Sheet3')
df
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
5230802420123080242迟培605089717671
6230802434723080243李华676184616578
7230802430723080243陈田767986694069
8230802432623080243余皓666785656171
9230802432023080243李嘉62作弊90606777
10230802434223080243李上初769084606660
11230802431023080243郭窦796784646479
12230802443523080244姜毅涛7771缺考617376
13230802443223080244赵宇747488687071
14230802444623080244周路768077617480
15230802442123080244林建祥727281639075
16230802443323080244李大强797677787070
17230802442823080244李侧通649691696077
18230802440223080244王慧737493707175
19230802442223080244李晓亮856085727283
20230802420123080242迟培605089717671
4. 导入MySQL库

Python 中操作MySQL 的模块是PyMy SQL,在导入MySQL 数据之前, 需
要安装PyMySQL 模块。目前Py由on3.x 仅支持PyMySQL ,不支持MySQLdb 。
安装PyMySQL ,命令为pip install pymysql

read_sql 函数可以导入My SQL 库。其命令格式如下:

read_sql(sql,conn)

其中:

  • sql 为从数据库中查询数据的SQL 语句;
  • conn 为数据库的连接对象,需要在程序中选创建。

示例代码如下:

import pandas as pd
import pymysql

dbconn=pymysql.connect(
    host="**********",
    database="kimbo",
    passwd="******",
    port=3306,
    charset='utf8'
    )
sqlcmd="select * from tabl e name"#SQL语句
a =pd.read_sql(sqlcmd , dbconn) #利用pandas模块导入MySQL数据
dbconn.close()
b=a.head()
print(b)

下面介绍读取MySQL 数据的其他方法。

方法一:

```python
一段代码,我懒得写了

方法二:

一段代码,懒得写了

2.4.2数据导出

1. 导出csv文件

to_csv 函数可以导出 csv 文件。其命令格式如下:

to_csv (file path,sep=",", index=TRUE, header=TRUE)

其中:

  • file_path 为文件路径:
  • sep 为分隔符,默认是逗号:
  • index 表示是否导出行序号,默认是 TR阻,导出行序号:
  • header 表示是否导出列名,默认是 TRUE ,导出列名。
【例 2-4 】导出 CSV 文件。
示例代码如下:
from pandas import DataFrame 
from pandas import Series 
df = DataFrame(
    {
    'age':Series([26, 85 , 64]), 
    'name':Series(['Ben','John','Jerry'])
    })
df 
agename
026Ben
185John
264Jerry
2. 导出Excel文件

to_excel 函数可以导出 Excel 文件。其命令格式如下:

to excel(file_path ,index=TRUE ,header=TRUE)

其中:

  • file_path 表示文件路径;
  • index 表示是否导出行序号,默认是 TRUE ,导出行序号;
  • header 表示是否导出 名,默认是 TRUE ,导 出列名。
例2-5 导出Excel文件。
示例代码如下:
from pandas import DataFrame
from pandas import Series
df=DataFrame(
    {'age':Series([26,85,64]),
    'name':Series(['Ben','John','Jerry'])
    })
df .to_excel ('./data/01.xlsx') #默认带上index
df.to_excel('./data/02.xlsx', index= False) #无index

3. 导出到MySQL

to_sql 函数可以将文件写入到MySQL数据库。其命令格式如下:

to_sql(tableName, con =数据库连接)

其中:

  • tableName 表示数据库中的表名;
  • con 表示数据库的连接对象,需要在程序中先创建。

示例代码如下:

#Python3.6 下利用PyMySQL 将Data Frame 文件写入到MySQL 数据库
from pandas import DataFrame
from pandas import Series
from sqlalchemy import create_engine
#启动引擎
engine = create_engine ("mysql+pymysql://user:password@host:port/databasename?charset=utf8")
#这里一定要写成mysql +pymysql ,不要写成mysql+mysqldb
#user:password 是账户和密码, host:port 是访问地址和端口,databasename 是库名
#DtaFrame 数据
df = DataFrame ( {' age ': Series ( [26, 85, 64 ]),' name ': Series ([' Ben ',' John ',' Jerry'])})
#存入MySQL
df.to_sql(
    name ='table name',
    con = engine,
    if_exists ='append',
    index = False,
    index_label = False)

## 2.5数据处理

***数据处理是一项复杂且繁琐的工作,同时也是整个数据分析过程中最为重要的环节。***<br>
***数据处理一方面能提高数据的质量,另一方面能让数据更好地适应特定的数据分析工具。数据处理的主要内容包括数据清洗、数据抽取、数据交换和数
据计算等。***

### 2.5.1数据清洗

在数据分析时,海量的原始数据中存在着大量不完整、不一致、有异常的
数据,严重影响到数据分析的结果,所以进行数据清洗就显得尤为重要。

数据清洗是数据价值链中最关键的步骤。垃圾数据,即使是通过最好的分
析,也将产生错误的结果,并误导业务本身。因此在数据分析过程中,数据清
洗占据了很大的工作量。

数据清洗就是处理缺失数据以及清除无意义的信息,如删除原始数据集中
的无关数据、重复数据,平滑噪声数据,筛选掉与分析主题无关的数据,处理
缺失值、异常值等。

#### 1. 重复值的处理

#### 例2-6 去掉重复数据

    示例代码如下:


```python
from pandas import DataFrame
from pandas import Series
df = DataFrame({
    'age':Series ([26 , 85 , 64 , 85 , 85]) ,
    'name': Series ([' Ben ',' John ',' Jerry ',' John ',' John'])
    })
df
agename
026Ben
185John
264Jerry
385John
485John
df.duplicated()
0    False
1    False
2    False
3     True
4    False
dtype: bool
df.duplicated('name')
0    False
1    False
2    False
3     True
4    False
dtype: bool
df.drop_duplicates('age')
agename
026Ben
185John
264Jerry
2. 缺失值处理

从统计上说,缺失的数据可能会产生有偏估计,从而使样本数据不能很
好地代表总体,而现实中绝大部分数据都包含缺失值,因此如何处理缺失值很
重要。

一般说来,缺失值的处理包括两个步骤,即缺失数据的识别和缺失数据的
处理。

  • 缺失数据的识别

Pandas 使用浮点值NaN 表示浮点和非浮点数组里的缺失数据,并使
用.isnull 和.notnull 函数来判断缺失情况。

例2-7 缺失数据的识别。
示例代码如下:
from pandas import DataFrame
from pandas import read_excel
df = read_excel('rz.xlsx', sheet_name='Sheet2')
df
学号姓名英语数分高代解几
02308024241成龙7640.023.060
12308024244周怡6647.047.044
22308024251张波85NaN45.060
32308024249朱浩6572.062.071
42308024219封印7361.047.046
52308024201迟培6071.076.071
62308024347李华6761.065.078
72308024307陈田7669.0NaN69
82308024326余皓6665.061.071
92308024219封印7361.047.046
df.isnull()
学号姓名英语数分高代解几
0FalseFalseFalseFalseFalseFalse
1FalseFalseFalseFalseFalseFalse
2FalseFalseFalseTrueFalseFalse
3FalseFalseFalseFalseFalseFalse
4FalseFalseFalseFalseFalseFalse
5FalseFalseFalseFalseFalseFalse
6FalseFalseFalseFalseFalseFalse
7FalseFalseFalseFalseTrueFalse
8FalseFalseFalseFalseFalseFalse
9FalseFalseFalseFalseFalseFalse
df.notnull()
学号姓名英语数分高代解几
0TrueTrueTrueTrueTrueTrue
1TrueTrueTrueTrueTrueTrue
2TrueTrueTrueFalseTrueTrue
3TrueTrueTrueTrueTrueTrue
4TrueTrueTrueTrueTrueTrue
5TrueTrueTrueTrueTrueTrue
6TrueTrueTrueTrueTrueTrue
7TrueTrueTrueTrueFalseTrue
8TrueTrueTrueTrueTrueTrue
9TrueTrueTrueTrueTrueTrue
  • 缺失数据的处理

对于缺失数据的处理方式有数据补齐、删除对应行、不处理等方法。

( 1 ) dropna(): 去除数据结构中值为空的数据行。

例2-8 删除数据为空所对应的行。
示例代码如下:
newDF=df.dropna ()
newDF
学号姓名英语数分高代解几
02308024241成龙7640.023.060
12308024244周怡6647.047.044
32308024249朱浩6572.062.071
42308024219封印7361.047.046
52308024201迟培6071.076.071
62308024347李华6761.065.078
82308024326余皓6665.061.071
92308024219封印7361.047.046

( 2 ) df. fillna(): 用其他数值替代NaN.

有些时候直接删除空数据会影响分析的结果,可以对数据进行填补。

例2-9 使用数值或者任意字符代替缺失值
示例代码如下:
df.fillna('?')
学号姓名英语数分高代解几
02308024241成龙7640.023.060
12308024244周怡6647.047.044
22308024251张波85?45.060
32308024249朱浩6572.062.071
42308024219封印7361.047.046
52308024201迟培6071.076.071
62308024347李华6761.065.078
72308024307陈田7669.0?69
82308024326余皓6665.061.071
92308024219封印7361.047.046

(3)df.fillna(method='pad):用前一个数据值替代NaN。

例2-10 用前一个数据值替代缺失值。
示例代码如下:
df . fillna(method='pad')
学号姓名英语数分高代解几
02308024241成龙7640.023.060
12308024244周怡6647.047.044
22308024251张波8547.045.060
32308024249朱浩6572.062.071
42308024219封印7361.047.046
52308024201迟培6071.076.071
62308024347李华6761.065.078
72308024307陈田7669.065.069
82308024326余皓6665.061.071
92308024219封印7361.047.046

(4) df.fillna(method=‘bfill’):用后一个数据值替代NaN.

例2-11 用后一个数据值替代NaN。
示例代码如下:
df.fillna(method='bfill')
学号姓名英语数分高代解几
02308024241成龙7640.023.060
12308024244周怡6647.047.044
22308024251张波8572.045.060
32308024249朱浩6572.062.071
42308024219封印7361.047.046
52308024201迟培6071.076.071
62308024347李华6761.065.078
72308024307陈田7669.061.069
82308024326余皓6665.061.071
92308024219封印7361.047.046

( 5 ) df. fillna( df.mean()):用平均数或者其他描述性统计量来代替NaN。

例2-12 使用均值来填补数据。
示例代码如下:
df.fillna(df.mean())
C:\Users\b2014\AppData\Local\Temp\ipykernel_4956\634187881.py:1: FutureWarning: Dropping of nuisance columns in DataFrame reductions (with 'numeric_only=None') is deprecated; in a future version this will raise TypeError.  Select only valid columns before calling the reduction.
  df.fillna(df.mean())
学号姓名英语数分高代解几
02308024241成龙7640.00000023.00000060
12308024244周怡6647.00000047.00000044
22308024251张波8560.77777845.00000060
32308024249朱浩6572.00000062.00000071
42308024219封印7361.00000047.00000046
52308024201迟培6071.00000076.00000071
62308024347李华6761.00000065.00000078
72308024307陈田7669.00000052.55555669
82308024326余皓6665.00000061.00000071
92308024219封印7361.00000047.00000046

“数分"列中有一个空值,该列除空值外的9 个数的均值为60.7777777 8’
故以60.777778 替代空值, “高代"列也一样。

( 6 ) df.fillna( df.mean()[‘填补列名气’计算均值的列名’]]):
的均值进行缺失值的处理。

【例2-13 】使用选择列的均值为某列空值来填补数据。
示例代码如下:
df.fillna(df.mean()['高代':'解几'])
C:\Users\b2014\AppData\Local\Temp\ipykernel_4956\1656679278.py:1: FutureWarning: Dropping of nuisance columns in DataFrame reductions (with 'numeric_only=None') is deprecated; in a future version this will raise TypeError.  Select only valid columns before calling the reduction.
  df.fillna(df.mean()['高代':'解几'])
学号姓名英语数分高代解几
02308024241成龙7640.023.00000060
12308024244周怡6647.047.00000044
22308024251张波85NaN45.00000060
32308024249朱浩6572.062.00000071
42308024219封印7361.047.00000046
52308024201迟培6071.076.00000071
62308024347李华6761.065.00000078
72308024307陈田7669.052.55555669
82308024326余皓6665.061.00000071
92308024219封印7361.047.00000046

用“解几"列的平均值来填补“高代"列的空缺值。

( 7 ) df.fillna( {'列名I ‘:值1, I 列名2’ :{直2 }) : 可以传入一个字典,对不同的
列填充不同的值。

例2- 14 为不同的列填充不同的值来填补数据。
示例代码如下:
df.fillna({'数分':100,'高代':0})
学号姓名英语数分高代解几
02308024241成龙7640.023.060
12308024244周怡6647.047.044
22308024251张波85100.045.060
32308024249朱浩6572.062.071
42308024219封印7361.047.046
52308024201迟培6071.076.071
62308024347李华6761.065.078
72308024307陈田7669.00.069
82308024326余皓6665.061.071
92308024219封印7361.047.046

“数分"列填充值为100, “高代"列填充值为0 。

( 8) strip ():清除字符型数据左右(首尾)指定的字符,
间的不清除。

例2-15 删除字符串左、右或首、尾指定的字符。
示例代码如下:
from pandas import DataFrame
from pandas import Series
df = DataFrame ( { 'age': Series ( [26 , 85 , 64 , 85, 85]) ,
'name': Series (['Ben','John','Jerry','John','John'])})
df
agename
026Ben
185John
264Jerry
385John
485John
df['name'].str.strip()
0      Ben
1     John
2    Jerry
3     John
4     John
Name: name, dtype: object

2.5.2 数据抽取

1. 字段抽取

字段抽取是指抽出某列上指定位置的数据做成新的列。其命令格式如下:

slice(start, stop)

其中:

  • start表示开始位置
  • stop表示结束位置
【例2-16 】从数据中抽出某列。
from pandas import DataFrame
from pandas import read_excel
df = read_excel ('i_nuc.xls', sheet_name= 'Sheet4')
df.head() #展示数据袤的前5 行,如显示后5 行,则为df.tail()
学号电话IP
023080242411.892225e+10221.205.98.55
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55
323080242491.882226e+10222.31.51.200
423080242191.892225e+10120.207.64.3
df [ '电话' ]=df ['电话' ]. astype (str) #astype ()转化类型
df [ '电话' ]
0     18922254812.0
1     13522255003.0
2     13422259938.0
3     18822256753.0
4     18922253721.0
5               nan
6     13822254373.0
7     13322252452.0
8     18922257681.0
9     13322252452.0
10    18922257681.0
11    19934210999.0
12    19934210911.0
13    19934210912.0
14    19934210913.0
15    19934210914.0
16    19934210915.0
17    19934210916.0
18    19934210917.0
19    19934210918.0
Name: 电话, dtype: object
bands =df['电话'].str.slice(0,3)#抽取手机号码的前三位,便于判断号码的品牌
bands
0     189
1     135
2     134
3     188
4     189
5     nan
6     138
7     133
8     189
9     133
10    189
11    199
12    199
13    199
14    199
15    199
16    199
17    199
18    199
19    199
Name: 电话, dtype: object
areas= df ['电话'].str.slice (3,7)#抽取手机号码的中间四位,以判断号码的地
areas
0     2225
1     2225
2     2225
3     2225
4     2225
5         
6     2225
7     2225
8     2225
9     2225
10    2225
11    3421
12    3421
13    3421
14    3421
15    3421
16    3421
17    3421
18    3421
19    3421
Name: 电话, dtype: object
tell= df['电话'].str.slice(7,11)#抽取手机号码的后四位
tell
0     4812
1     5003
2     9938
3     6753
4     3721
5         
6     4373
7     2452
8     7681
9     2452
10    7681
11    0999
12    0911
13    0912
14    0913
15    0914
16    0915
17    0916
18    0917
19    0918
Name: 电话, dtype: object
2. 字段拆分

宇段拆分是指按指定的字符sep , 拆分己有的字符串。其命令格式如下:

split (sep, n , expand=False)

参数说明:
* sep 表示用于分隔字符串的分隔符:
* n 表示分割后新增的列数;
& expand 表示是否展开为数据框,默认为FALSE

返回值: expand 为TRUE ,返回DaraFrame ; expand 为False ,返回Series

#### 【例2-17】拆分字符串为指定的列数。
    示例代码如下:


```python
from pandas import DataFrame
from pandas import read_excel 
df= read_excel(r'i_nuc.xls', sheet_name='Sheet4')
df
学号电话IP
023080242411.892225e+10221.205.98.55
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55
323080242491.882226e+10222.31.51.200
423080242191.892225e+10120.207.64.3
52308024201NaN222.31.51.200
623080243471.382225e+10222.31.59.220
723080243071.332225e+10221.205.98.55
823080243261.892226e+10183.184.230.38
923080243201.332225e+10221.205.98.55
1023080243421.892226e+10183.184.230.38
1123080243101.993421e+10183.184.230.39
1223080244351.993421e+10185.184.230.40
1323080244321.993421e+10183.154.230.41
1423080244461.993421e+10183.184.231.42
1523080244211.993421e+10183.154.230.43
1623080244331.993421e+10173.184.230.44
1723080244281.993421e+10NaN
1823080244021.993421e+10183.184.230.4
1923080244221.993421e+10153.144.230.7
df['IP'].str.strip ()#IP先转为str,再删除首尾空格
0       221.205.98.55
1     183.184.226.205
2       221.205.98.55
3       222.31.51.200
4        120.207.64.3
5       222.31.51.200
6       222.31.59.220
7       221.205.98.55
8      183.184.230.38
9       221.205.98.55
10     183.184.230.38
11     183.184.230.39
12     185.184.230.40
13     183.154.230.41
14     183.184.231.42
15     183.154.230.43
16     173.184.230.44
17                NaN
18      183.184.230.4
19      153.144.230.7
Name: IP, dtype: object
newDF=df ['IP'].str.split ('.',1,True)#按第一个"."分成两列,1表示新增的列数
newDF
01
0221205.98.55
1183184.226.205
2221205.98.55
322231.51.200
4120207.64.3
522231.51.200
622231.59.220
7221205.98.55
8183184.230.38
9221205.98.55
10183184.230.38
11183184.230.39
12185184.230.40
13183154.230.41
14183184.231.42
15183154.230.43
16173184.230.44
17NaNNaN
18183184.230.4
19153144.230.7
newDF.columns=['IP1','IP2-4']#给第1列、第2列增加列名称
newDF
IP1IP2-4
0221205.98.55
1183184.226.205
2221205.98.55
322231.51.200
4120207.64.3
522231.51.200
622231.59.220
7221205.98.55
8183184.230.38
9221205.98.55
10183184.230.38
11183184.230.39
12185184.230.40
13183154.230.41
14183184.231.42
15183154.230.43
16173184.230.44
17NaNNaN
18183184.230.4
19153144.230.7
3. 重置索引

重置索引是指指定某列为索引,以便于对其他数据进行操作。其命令格式如下:

df.set _index ('列名')
【例2- 18 】对数据框进行重置索引。
示例代码如下:  
from pandas import DataFrame
from pandas import Series 
df = DataFrame ( 
    {'age' :Series ( [26 , 85 , 64, 85, 85]),
    'name':Series(['Ben','John','Jerry','John','John'])}
    ) 
df1=df.set_index('name') #以name列为新的索引 
df1
age
name
Ben26
John85
Jerry64
John85
John85
4. 记录抽取

记录抽取是指根据一定的条件,对数据进行抽取 其命令格式如下:

df[condition] 

参数说明:
condition 表示过滤条件。
返回值: DataFrame
常用的 condition 类型有:

  • 比较运算:=、<、>、>=、<=、!=,如df[df.comments>l0000)]:
  • 范围运算:between(left,right),如df[df.comments.between(1000,l0000)]:
  • 空置运算:pandas…isnull(column),如df[df.title.isnull(]; 字符匹配:str.contains(patten,na=False),如df[df.title.str.contains(‘电台’,na=False)];
  • 逻辑运算:&(与)、|(或)、not(取反),如df[(df.comments>=l000)& (df.comments-<=10000)]与df[df.comments.between(1000,10000)]等价。
【例2-19 】按条件抽取数据。
示例代码如下:
import pandas 
from pandas import read_excel 
df =read_excel(r'i_nuc.xls', sheet_name='Sheet4') 
df.head()
学号电话IP
023080242411.892225e+10221.205.98.55
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55
323080242491.882226e+10222.31.51.200
423080242191.892225e+10120.207.64.3
df[df.电话==13322252452]
学号电话IP
723080243071.332225e+10221.205.98.55
923080243201.332225e+10221.205.98.55
df[df.电话>13322252452]
学号电话IP
023080242411.892225e+10221.205.98.55
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55
323080242491.882226e+10222.31.51.200
423080242191.892225e+10120.207.64.3
623080243471.382225e+10222.31.59.220
823080243261.892226e+10183.184.230.38
1023080243421.892226e+10183.184.230.38
1123080243101.993421e+10183.184.230.39
1223080244351.993421e+10185.184.230.40
1323080244321.993421e+10183.154.230.41
1423080244461.993421e+10183.184.231.42
1523080244211.993421e+10183.154.230.43
1623080244331.993421e+10173.184.230.44
1723080244281.993421e+10NaN
1823080244021.993421e+10183.184.230.4
1923080244221.993421e+10153.144.230.7
df[df.电话.between(13400000000,13999999999)]
学号电话IP
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55
623080243471.382225e+10222.31.59.220
df [df.IP.isnull ()]
学号电话IP
1723080244281.993421e+10NaN
df [df.IP.str.contains ('222.',na=False) ]
学号电话IP
323080242491.882226e+10222.31.51.200
52308024201NaN222.31.51.200
623080243471.382225e+10222.31.59.220
5. 随机抽样

随机抽样是指随机从数据中按照一定的行数或者比例抽取数据。
随机抽样函数格式如下:

numpy. random.randint (start, end, num)

参数说明:

  • startg表示范围的开始值;
  • end表示范围的结束值;num表示抽样个数。
  • 返回值:行的索引值序列。
【例2-20 ]逻辑条件切片。
示例代码如下:
from pandas import read_excel 
df= read_excel(r'i_nuc.xls' ,sheet_name='Sheet4') 
df.head()
学号电话IP
023080242411.892225e+10221.205.98.55
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55
323080242491.882226e+10222.31.51.200
423080242191.892225e+10120.207.64.3
df[df.电话>=18822256753]#单个逻辑条件
学号电话IP
023080242411.892225e+10221.205.98.55
323080242491.882226e+10222.31.51.200
423080242191.892225e+10120.207.64.3
823080243261.892226e+10183.184.230.38
1023080243421.892226e+10183.184.230.38
1123080243101.993421e+10183.184.230.39
1223080244351.993421e+10185.184.230.40
1323080244321.993421e+10183.154.230.41
1423080244461.993421e+10183.184.231.42
1523080244211.993421e+10183.154.230.43
1623080244331.993421e+10173.184.230.44
1723080244281.993421e+10NaN
1823080244021.993421e+10183.184.230.4
1923080244221.993421e+10153.144.230.7
df [(df.电话>=13422259938 )&(df.电话<13822254373)]
学号电话IP
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55

这种方式获取的数据切片都是 DataFrame

【例2-21 ]随机抽取数据。
示例代码如下:
from pandas import read_excel
df= read_excel(r'i_nuc.xls',sheet_name='Sheet4') 
df.head()
学号电话IP
023080242411.892225e+10221.205.98.55
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55
323080242491.882226e+10222.31.51.200
423080242191.892225e+10120.207.64.3
r= np.random.randint(0,10 , 3) 
r
array([2, 8, 3])
df.loc[r, :] #抽取 行数据,也可以直接写成 df.loc[r)
学号电话IP
223080242511.342226e+10221.205.98.55
823080243261.892226e+10183.184.230.38
323080242491.882226e+10222.31.51.200
6. 通过索引抽取数据

( 1 )使用索引名(标签)选取数据: f. oc 行标签,列标签
示例代码如下:

df=df. set_index ('学号')#更改“学号”列为新的索引
df . head()
电话IP
学号
23080242411.892225e+10221.205.98.55
23080242441.352226e+10183.184.226.205
23080242511.342226e+10221.205.98.55
23080242491.882226e+10222.31.51.200
23080242191.892225e+10120.207.64.3
df.loc[2308024241:2308024201]#选取a到b行的数据:df . loc [’ a ’:’ b ’ ] 

电话IP
学号
23080242411.892225e+10221.205.98.55
23080242441.352226e+10183.184.226.205
23080242511.342226e+10221.205.98.55
23080242491.882226e+10222.31.51.200
23080242191.892225e+10120.207.64.3
2308024201NaN222.31.51.200
df.loc[:,'电话'].head()#选取“电话”列的数据
学号
2308024241    1.892225e+10
2308024244    1.352226e+10
2308024251    1.342226e+10
2308024249    1.882226e+10
2308024219    1.892225e+10
Name: 电话, dtype: float64

df.loc的第一个参数是行标签,第二个参数为列标签(可选参数,默认为所有列标签),两个参数既可以是列表也可以是单个字符,如果两个参数都为列表则返回的是DataFrame,否则为Series。

import pandas as pd
df=pd.DataFrame({'a':[1,2,3],'b':['a','b','c'],'c':["A","B","C"]}) 
df
abc
01aA
12bB
23cC
df.loc[1] #抽取index=l的行,但返回的是Series, 而不是DaTa Frame
a    2
b    b
c    B
Name: 1, dtype: object
df.loc[[1,2]]#抽取index=1和2的两行
abc
12bB
23cC

(2)使用索引号选取数据: df. iloc [行索引号,列索引号]

【例2-22 ]使用索引号抽取数据。
示例代码如下:
from pandas import read_excel
df = read_excel (r'i_nuc.xls', sheet_name= 'Sheet4') 
df=df.set_index ('学号')
df.head ()
电话IP
学号
23080242411.892225e+10221.205.98.55
23080242441.352226e+10183.184.226.205
23080242511.342226e+10221.205.98.55
23080242491.882226e+10222.31.51.200
23080242191.892225e+10120.207.64.3
df.iloc [1,0]#选取第2行、第1列的值,返回的为单个值
13522255003.0
df.iloc[[0,2],:]#选取第1行和第3行的数据
电话IP
学号
23080242411.892225e+10221.205.98.55
23080242511.342226e+10221.205.98.55
df.iloc[0:2,:]#选取第1行到第3行(不包含第3行)的数据
电话IP
学号
23080242411.892225e+10221.205.98.55
23080242441.352226e+10183.184.226.205
df.iloc [:,1]#选取所有记录的第2列的值,返回的为一个Series
学号
2308024241        221.205.98.55
2308024244      183.184.226.205
2308024251        221.205.98.55
2308024249        222.31.51.200
2308024219         120.207.64.3
2308024201        222.31.51.200
2308024347        222.31.59.220
2308024307    221.205.98.55    
2308024326       183.184.230.38
2308024320    221.205.98.55    
2308024342       183.184.230.38
2308024310       183.184.230.39
2308024435       185.184.230.40
2308024432       183.154.230.41
2308024446       183.184.231.42
2308024421       183.154.230.43
2308024433       173.184.230.44
2308024428                  NaN
2308024402        183.184.230.4
2308024422        153.144.230.7
Name: IP, dtype: object
df.iloc[1,:]#选取第2行数据,返回的为一个Series
电话        13522255003.0
IP      183.184.226.205
Name: 2308024244, dtype: object
【例2-23 】ix 的使用。
示例代码如下:
import pandas as pd 
index_loc = ['a', 'b'] 
index_iloc = [1,2] 
data = [[1,2,3,4], [5, 6,7, 8]]
columns = ['one','two','three','four'] 
df1 = pd.DataFrame(data=data, index=index_loc,columns=columns) 
df2 = pd.DataFrame(data=data, index=index_iloc,columns=columns)
df1.loc['a']#按索引名提取
one      1
two      2
three    3
four     4
Name: a, dtype: int64
df1.iloc[0]#按索号提取
one      1
two      2
three    3
four     4
Name: a, dtype: int64
df2.iloc[0]#按索引号提取,会报错,因索引名是int
one      1
two      2
three    3
four     4
Name: 1, dtype: int64
7. 字典数据抽取

字典数据抽取是指将字典数据抽取为 dataframe ,有以下三种方法。

(1)字典的key和value各作为一列

示例代码如下:

import pandas 
from pandas import DataFrame 
d1={'a':'[1,2,3]','b':'[0,1,2]'} 
a1=pandas.DataFrame.from_dict(d1,orient='index') #将字典转为dataframe,且key列做成了index 
a1.index.name ='key'#将index的列名改成key'
b1=a1.reset_index()   #重新增加index,并将原index 做成了'key'列 b1.columns=['key','value'] #对列重新命名为'key'和value' 
b1
key0
0a[1,2,3]
1b[0,1,2]

(2)字典里的每一个元素作为一列(同长)

示例代码如下:

d2={'a':[1,2,3],'b':[4,5,6]} #字典的value必须长度相等 
a2=DataFrame (d2) 
a2
ab
014
125
236

(3)字典里的每一个元素作为一列(不同长)

示例代码如下:

d={'one':pandas.Series([1,2,3]),'two':pandas.Series ([1,2,3,4])} #字典的value长度可以不相等 
df= pandas.DataFrame(d) 
df
onetwo
01.01
12.02
23.03
3NaN4

2.5.3 插入记录

Pandas里并没有直接指定索引的插入行的方法,所以要用户自行设置。

示例代码如下:

import pandas as pd
df=pd.DataFrame({'a':[1,2,3],'b':['a','b','c'],'c':["A","B","C"]}) 
df
abc
01aA
12bB
23cC
line= pd.DataFrame({df.columns[0]:"--",df.columns[1]:"--",df.columns[2]:"--"},index=[1])#抽取df的index=1的行,并将此行第一列 columns[0]赋值"--",第二、三列同样赋值"--"
line
abc
1------
df0= pd.concat([df. loc[:0], line, df. loc[1:11]])
df0
abc
01aA
1------
12bB
23cC

这里df.loc[:0]不能写成df.loc[0],因为df.loc[0]表示抽取index=0的行,返回的是Series不是DataFrame。

dfo的索引没有重新给出新的索引,需要对索引进行重新设定。

方法一:

先利用reset_index()函数给出新的索引,但是原索引将作为新增加的index 列,再对新增加的列利用drop函数,删除新增的index列。

示例代码如下:
此方法虽然有点繁琐笨拙,但是有时候确实有输出原索引的需求。

示例代码如下:

df1=df0.reset_index()#重新给出索引,后面详细解释
df1
indexabc
001aA
11------
212bB
323cC
df2=df1.drop('index', axis=1)#删除index列
df2
abc
01aA
1------
22bB
33cC

方法二:

直接对reset_index()函数添加drop=True参数,即删除了原索引并给出新的索引。

示例代码如下:

df2=pd.concat([df.loc[:0],line,df.loc[1:]]).reset_index (drop=True)
df2
abc
01aA
1------
22bB
33cC

方法三:

先找出df0的索引长度:lenth=len(dfo.index),再利用整数序列函数生成索引:range(lenth),然后把生成的索引赋值给dfo.index。

示例代码如下:

df0.index=range (len (df0.index))
df0
abc
01aA
1------
22bB
33cC

2.5.4 修改记录

修改记录(数据)是常有的事情,比如数据中有些需要整体替换,有些需要个别修改等情况经常会出现。

1. 整体替换

整列、整行的替换这里不多说,很容易做到。例如执行语句: df['平时成绩]=score_2,该语句中score_2是将被填进去的数据列(可以是列表或者Series)

2. 个别修改

这里要说的是整个df(数据框) 中可能各列都有NaN, 现在需要把NaN替换成0以便于计算, 类似于Word软件中“查找替换”(Ctrl+H) 功能。

【例2-24 】替换。
示例代码如下:
from pandas import read_excel 
df=pd.read_excel(r'i_nuc.xls',sheet_name='Sheet3')
df.head()
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746

(1)单值替换

其命令格式如下:

df.replace('B','A')#用A替换B,也可以用df.replace ({'B':'A')命令实现
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
5230802420123080242迟培605089717671
6230802434723080243李华676184616578
7230802430723080243陈田767986694069
8230802432623080243余皓666785656171
9230802432023080243李嘉62作弊90606777
10230802434223080243李上初769084606660
11230802431023080243郭窦796784646479
12230802443523080244姜毅涛7771缺考617376
13230802443223080244赵宇747488687071
14230802444623080244周路768077617480
15230802442123080244林建祥727281639075
16230802443323080244李大强797677787070
17230802442823080244李侧通649691696077
18230802440223080244王慧737493707175
19230802442223080244李晓亮856085727283
20230802420123080242迟培605089717671

(2)指定列单值替换

df.replace ({'体育' :'作弊'},0)#用0替换“体育”列中“作弊”
df.replace ({'体育':'作弊','军训':'缺考'},0) #用0替换“体育”列中“作弊”以及“军训”列中的“缺考”

下面用具体的例子说明,例如:

df.replace ({'体育' :'作弊'},0)#用0替换“体育”列中“作弊”
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
5230802420123080242迟培605089717671
6230802434723080243李华676184616578
7230802430723080243陈田767986694069
8230802432623080243余皓666785656171
9230802432023080243李嘉62090606777
10230802434223080243李上初769084606660
11230802431023080243郭窦796784646479
12230802443523080244姜毅涛7771缺考617376
13230802443223080244赵宇747488687071
14230802444623080244周路768077617480
15230802442123080244林建祥727281639075
16230802443323080244李大强797677787070
17230802442823080244李侧通649691696077
18230802440223080244王慧737493707175
19230802442223080244李晓亮856085727283
20230802420123080242迟培605089717671

(3)多值替换
多值替换可用如下命令:

df.replace(['成龙','周怡'],['陈龙','周毅'])#用“陈龙”替换“成龙”,用“周毅”替换“周怡”

还可以用下面两种命令方式,效果一样:

df.replace({'成龙':'陈龙','周怡':'周毅'})
df.replace({'成龙','周怡'},{'陈龙','周毅'})

示例代码如下:

df.replace({'成龙':'陈龙','周怡':'周毅'})
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242陈龙767877402360
1230802424423080242周毅669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
5230802420123080242迟培605089717671
6230802434723080243李华676184616578
7230802430723080243陈田767986694069
8230802432623080243余皓666785656171
9230802432023080243李嘉62作弊90606777
10230802434223080243李上初769084606660
11230802431023080243郭窦796784646479
12230802443523080244姜毅涛7771缺考617376
13230802443223080244赵宇747488687071
14230802444623080244周路768077617480
15230802442123080244林建祥727281639075
16230802443323080244李大强797677787070
17230802442823080244李侧通649691696077
18230802440223080244王慧737493707175
19230802442223080244李晓亮856085727283
20230802420123080242迟培605089717671

2.5.5 交换行或列

可以直接使用df.reindex方法交换数据中的两行或两列,读者可以自己DY。reindex函数后面将详细讲解。

【例2-25 】行、列交换。
示例代码如下:  
import pandas as pd 
df=pd.DataFrame({'a':[1,2,3],'b':['a','b','c'],'c':["A","B","C"]})
df
abc
01aA
12bB
23cC
hang= [0,2,1]
df.reindex (hang)
abc
01aA
23cC
12bB
lie=['a','c','b']
df.reindex(columns=lie)
acb
01Aa
12Bb
23Cc

2.5.6 排名索引

1. so_index :重新排序

Series的sort index(ascending-True) 方法可以对index进行排序操作,ascending参数用于控制升序(ascending=True) 或降序(ascending-False) , 默认为升序。

【例2-26 ] 重新排序。

示例代码如下:
from pandas import DataFrame 
df0={'Ohio':[0, 6, 3] , 'Texas':[7, 4, 1] , 'California':[2, 8, 5] }
df=DataFrame(df0, index=['a', 'd', 'c'])
df
OhioTexasCalifornia
a072
d648
c315
df.sort_index()#默认按index升序排序,降序:df.sort index(ascending=False)
OhioTexasCalifornia
a072
c315
d648
df.sort_index('by'=='Ohio')#按Ohio列升序排序,也可以是多列by=['Ohio', 'Texas']
C:\Users\b2014\AppData\Local\Temp\ipykernel_4956\45844033.py:1: FutureWarning: In a future version of pandas all arguments of DataFrame.sort_index will be keyword-only.
  df.sort_index('by'=='Ohio')#按Ohio列升序排序,也可以是多列by=['Ohio', 'Texas']
OhioTexasCalifornia
a072
c315
d648
df.sort_index('by'==['California','Texas'])
C:\Users\b2014\AppData\Local\Temp\ipykernel_4956\3360228840.py:1: FutureWarning: In a future version of pandas all arguments of DataFrame.sort_index will be keyword-only.
  df.sort_index('by'==['California','Texas'])
OhioTexasCalifornia
a072
c315
d648
df.sort_index(axis=1)
CaliforniaOhioTexas
a207
d864
c531

排名方法(Series.rank(method=-‘average’,ascending-True)与排序的不同之处在于,它会把对象的values替换成名次(从1到n),对于平级项可以通过该方法里的method参数来处理,method参数有四个可选项:average、min、max、first。举例如下:

from pandas import Series 
ser=Series ([3,2,0,3], index=list ('abcd'))
ser
a    3
b    2
c    0
d    3
dtype: int64
ser.rank()
a    3.5
b    2.0
c    1.0
d    3.5
dtype: float64
ser.rank()
a    3.5
b    2.0
c    1.0
d    3.5
dtype: float64
ser.rank(method='min')
a    3.0
b    2.0
c    1.0
d    3.0
dtype: float64
ser.rank(method='max')
a    4.0
b    2.0
c    1.0
d    4.0
dtype: float64
ser.rank(method='first')
a    3.0
b    2.0
c    1.0
d    4.0
dtype: float64
2. reindex :重新索引

Series对象的重新索引通过其reindext(index-=None,kwargs)方法实现kwargs中常用的参数有两个:method-=None和fill value=np.NaN。

【例2-27 ]排序。

示例代码如下:
import pandas as pd 
df=pd.DataFrame({'a':[1,2,3,0],'c':["A","E","B","c"],'d':['a','b','d','c'],'b':[1,3,2,5],},index=[1,3,2,4])
df
acdb
11Aa1
32Eb3
23Bd2
40cc5
df.sort_index()
acdb
11Aa1
23Bd2
32Eb3
40cc5
df.sort_index(axis=1)#队列进行排序,降序添加ascending=False
abcd
111Aa
323Eb
232Bd
405cc
df.sort_index('by'=='a')#对a列进行排序,by仅用于列main:1:FutureWarning:by argument to sort index is deprecated,pls use.sort values(by=...)
C:\Users\b2014\AppData\Local\Temp\ipykernel_4956\2549661233.py:1: FutureWarning: In a future version of pandas all arguments of DataFrame.sort_index will be keyword-only.
  df.sort_index('by'=='a')#对a列进行排序,by仅用于列main:1:FutureWarning:by argument to sort index is deprecated,pls use.sort values(by=...)
acdb
11Aa1
23Bd2
32Eb3
40cc5
df.sort_index('by'==['a','b'])#对a、b两列依次排序main:1:FutureWarning:by argument to sort_index is deprecated,pls use.sort values(by=..…)
C:\Users\b2014\AppData\Local\Temp\ipykernel_4956\2730870432.py:1: FutureWarning: In a future version of pandas all arguments of DataFrame.sort_index will be keyword-only.
  df.sort_index('by'==['a','b'])#对a、b两列依次排序main:1:FutureWarning:by argument to sort_index is deprecated,pls use.sort values(by=..…)
acdb
11Aa1
23Bd2
32Eb3
40cc5

df.sort_index(by='a)对列进行排序时也可以使用dfsort_values’a)。

df.sort_values(['a','b'])
acdb
40cc5
11Aa1
32Eb3
23Bd2

【例2-28 】重新索引。

示例代码如下:
from pandas import Series 
ser=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])
A=['a','b','c','d','e']
ser.reindex(A)
a   -5.3
b    7.2
c    3.6
d    4.5
e    NaN
dtype: float64
ser=ser.reindex(A,fill_value=0)
ser
a   -5.3
b    7.2
c    3.6
d    4.5
e    0.0
dtype: float64
ser.reindex(A,method='ffill')
a   -5.3
b    7.2
c    3.6
d    4.5
e    0.0
dtype: float64
ser.reindex(A,fill_value=0,method='ffill')
a   -5.3
b    7.2
c    3.6
d    4.5
e    0.0
dtype: float64
3. set_index :重置索引

前面介绍重置索引时讲过 set_index(),可以对 DataFrame 重新设置某列为索引。
其命令格式如下:
DataFrame.set_index(
keys,
drop=True,
append=False,
inplace=False)
其中:

  • append=True时,保留原索引并添加新索引;
  • drop为False时,保留被作为索引的列;
  • inplace为True时,在原数据集上修改。

DataFrame 可以通过set index方法不仅可以设置单索引,而且可以设置复合索引,打造层次化索引。

【例2-29 】复合索引。

示例代码如下:
import pandas as pd 
df=pd.DataFrame({'a':[1,2,3],'b':['a','b','c'],'c':["A","B","C"]})
df
abc
01aA
12bB
23cC
df.set_index(
    ['b','c'],
    drop=False,#保留b、c两列append-True,#保留原来的索引
    inplace=False)#保留原df,即不在原df上修改,生成新的数据框
abc
bc
aA1aA
bB2bB
cC3cC
4. reset index :索引还原

reset_index 可以还原索引,使索引重新变为默认的整型索引,即 reset_index 是set_index的“逆运算”。
其命令格式如下:

df.reset_index(level=None,drop=False,inplace=False,col_level=0,col_fill=")

参数level控制了具体要还原的那个等级的索引。

【例2-30 】索引还原。
示例代码如下:
import pandas as pd 
df = pd. DataFrame ({ 'a' : [1,2,3], 'b' : ['a' , ' b' , ' c' ], 'c' : ["A","B","C"]})
df1=df.set_index(['b' , 'c'],drop=False, append=True, inplace=False)
df1
abc
bc
0aA1aA
1bB2bB
2cC3cC
df1.reset_index(level='b',drop=True,inplace=False,col_level='0')
abc
c
0A1aA
1B2bB
2C3cC

注意在使用sort_index对DataFrame进行排序的时候,不能直接对index和columns都含有的字段进行排序,会报错。

2.5.7 数据合并

1. 记录合井

记录合并是指两个结构相同的数据框合并成一个数据框, 也就是在 个数
据框中追加另一个数据框的数据记录。

其命令格式如下:

concat([dataFramel,dataFrame2……1)

参数说明:DataFrame1表示数据框。

返回值:DataFrame。

【例2-31】合并两个数据框的记录。
示例代码如下:
from pandas import read_excel 
df1 = read_excel('i_nuc.xls',sheet_name='Sheet3')
df1.head()
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
df2=read_excel(r'i_nuc.xls',sheet_name='Sheet5')
df2
学号班级姓名性别英语体育军训数分高代解几
0230802450123080245李同649691696077
1230802450223080245王致意737493707175
2230802450323080245李同维856085727283
3230802450423080245池莉605089717671
df=pandas.concat ([df1, df2])
df
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
5230802420123080242迟培605089717671
6230802434723080243李华676184616578
7230802430723080243陈田767986694069
8230802432623080243余皓666785656171
9230802432023080243李嘉62作弊90606777
10230802434223080243李上初769084606660
11230802431023080243郭窦796784646479
12230802443523080244姜毅涛7771缺考617376
13230802443223080244赵宇747488687071
14230802444623080244周路768077617480
15230802442123080244林建祥727281639075
16230802443323080244李大强797677787070
17230802442823080244李侧通649691696077
18230802440223080244王慧737493707175
19230802442223080244李晓亮856085727283
20230802420123080242迟培605089717671
0230802450123080245李同649691696077
1230802450223080245王致意737493707175
2230802450323080245李同维856085727283
3230802450423080245池莉605089717671

可以看到两个数据框的数据记录都合并到一起了,实现了数据记录的追加,但是记录的索引并没有顺延,仍然保持着原有的状态。前面讲过合并两个数据框的append方法,再复习一下。

其命令格式如下:

df.append(df2,ignore_index=True)#把df2追加到df上,index直接顺延同样,在concat方法中加一个ignore_index=True参数,index即可顺延。

其命令格式如下:

pandas.concat([df1,df2],ignore_index=True)
2. 字段合并

学段合并是指将同一个数据框中的不同列进行合并,形成新的列。其命令格式如下:
X =x1+x2+*…
参数说明:

  • x1表示数据列1;
  • x2表示数据列2。
    返回值: Series。合并前的系列,要求合并的系列长度一致。
【例 -32 】多个字段合并成 个新的宇段
示例代码如下:
from pandas import DataFrame 
df = DataFrame ( {'band':[189,135,134,133],'area':['0351','0352','0354','0341'],'num': [2190,8513,8080,7890]})
df
bandareanum
018903512190
113503528513
213403548080
313303417890
3. 字段匹配

字段匹配是指不同结构的数据框(两个或两个以上的数据框),按照一定的条件进行匹配合并,即追加列,类似于Excel中的VLOOKUP函数。例如,有两个数据表,第一个表中有学号、姓名,第二个表中有学号、手机号,现需要整理一份数据表,包含学号、姓名、手机号,此时则需要用到merge函数。

其命令格式如下:

merge(x,Y,left _on,right_on)

参数说明:

  • x表示第一个数据框;
  • y表示第二个数据框;
  • left_on表示第一个数据框的用于匹配的列;
  • right_on表示第二个数据框的用于匹配的列。

    返回值:DataFrame。
【例2-33 】按指定唯一字段匹配增加列。
示例代码如下:
import pandas as pd 
from pandas import read_excel 
df1= pd.read_excel('i_nuc.xls',sheet_name ='Sheet3')
df1.head()
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
df2=pd.read_excel(r'i_nuc.xls',sheet_name ='Sheet4')
df2.head ()
学号电话IP
023080242411.892225e+10221.205.98.55
123080242441.352226e+10183.184.226.205
223080242511.342226e+10221.205.98.55
323080242491.882226e+10222.31.51.200
423080242191.892225e+10120.207.64.3
df-pd.merge(df1,df2,left_on='学号',right_on='学号')
df.head()
bandareanum
018903512190
113503528513
213403548080
313303417890

2.5.8 数据计算

1. 简单计算

简单计算是指通过对各字段进行加、减、乘、除等四则算术运算,得出的结果作为新的字段

【例2-34】数据框的计算。
示例代码如下:
from pandas import read_excel 
df = read_excel (r'i_nuc.xls',sheet_name='Sheet3')
df.head ()
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
jj=df['解几'].astype (int)#将df 中的“解几”转化为int类型
gd=df['高代'].astype(int)
df['数分+解几']=jj+gd #在df 中新增“数分+解几”列,值为:jj+gd 
df.head()
学号班级姓名性别英语体育军训数分高代解几数分+解几
0230802424123080242成龙76787740236083
1230802424423080242周怡66917547474491
2230802425123080242张波858175454560105
3230802424923080242朱浩655080726271133
4230802421923080242封印73889261474693
2. 数据标准化

数据标准化(归一化)处理是数据分析和挖掘的一项基础工作,不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。原始数据经过数据标准化处理后,各指标处于同一数量级,适合进行综合对比评价。

数据标准化常用的方法为:

(1) min-max标准化(Min-Max Normalization)

又名离差标准化,是对原始数据的线性转化公式如下:
X ∗ = ( x − m i n ) / ( m a x − m i n ) X*=(x-min)/(max-min) X=(xmin)/(maxmin)
其中,max为样本最大值;min为样本最小值。当有新数据加入时需要重新进行数据归一化。

【例2-35】数据标准化。
from pandas import read_excel 
df = read_excel(r'i_nuc.xls',sheet_name='Sheet3')
df.head()
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
scale= (df.数分.astype(int)-df.数分.astype (int).min() )/(df.数分.astype(int).max ()-df.数分.astype(int).min())
scale.head ()
0    0.000000
1    0.184211
2    0.131579
3    0.842105
4    0.552632
Name: 数分, dtype: float64

(2) Z-score 标准化方法Z-score

标准化方法适用于属性A的最大值和最小值未知的情况,或有超出取值范围的离群数据的情况。这种方法给予原始数据的均值(Mean)和标准差(Standard Deviation)进行数据的标准化。经过处理的数据符合标准正态分布,即均值为0,标准差为1,转化函数为:
X ∗ = ( x − μ ) / σ X^{*}=(x-\mu) / \sigma X=(xμ)/σ
其中,为所有样本数据的均值,。为所有样本数据的标准差。

将数据按其属性(按列进行)减去其均值,并除以其标准差,得到的结果是,对于每个属性(每列)来说所有数据都聚集在0附近,标准差为1。

使用sklearn.preprocessing.scale()函数,可以直接将给定数据进行标准化:

from sklearn import preprocessing 
import numpy as np 
df1=df['数分']
df_scaled = preprocessing.scale (df1)
df_scaled
array([-2.50457384, -1.75012229, -1.96567988,  0.94434751, -0.2412192 ,
        0.83656872, -0.2412192 ,  0.62101114,  0.18989597, -0.34899799,
       -0.34899799,  0.08211717, -0.2412192 ,  0.51323234, -0.2412192 ,
       -0.02566162,  1.59102027,  0.62101114,  0.72878993,  0.94434751,
        0.83656872])

也可以使用sklearn.preprocessing.StandardScaler类,使用该类的好处在于可以保存训练集中的参数(均值、标准差),直接使用其对象转换测试集数据:

X = np.array([[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]])
X
array([[ 1., -1.,  2.],
       [ 2.,  0.,  0.],
       [ 0.,  1., -1.]])
scaler = preprocessing.StandardScaler().fit(X)
scaler
StandardScaler()
scaler.mean_
array([1.        , 0.        , 0.33333333])
scaler.transform(X)
array([[ 0.        , -1.22474487,  1.33630621],
       [ 1.22474487,  0.        , -0.26726124],
       [-1.22474487,  1.22474487, -1.06904497]])
#可以直接使用训练集对测试集数据进行转换
scaler.transform ([ [-1., 1., 0.]])
array([[-2.44948974,  1.22474487, -0.26726124]])

2.5.9 数据分组

数据分组是指根据数据分析对象的特征,按照一定的数据指标, 把数据划
分为不同的区间来进行研究,以揭示其内在的联系和规律性。简单来说,就是
新增一列, 将原来的数据按照其性质归入新的类别中。其命令格式如下:

【例2-36 】数据分组。
示例代码如下:
from pandas import read_excel 
import pandas as pd 
df = pd.read_excel (r'rz.xlsx')
df.head ()#查看前5行数据
学号班级姓名性别英语体育军训数分高代解几
0230802424123080242成龙767877402360
1230802424423080242周怡669175474744
2230802425123080242张波858175454560
3230802424923080242朱浩655080726271
4230802421923080242封印738892614746
df.shape
(21, 10)
bins=[min(df.解几)-1,60,70,80,max(df.解几)+1]
lab=["不及格","及格","良好","优秀"]
demo=pd.cut (df.解几,bins,right=False, labels=lab)
demo.head()#仅显示前5行数据
0     及格
1    不及格
2     及格
3     良好
4    不及格
Name: 解几, dtype: category
Categories (4, object): ['不及格' < '及格' < '良好' < '优秀']
df[ 'demo']=demo 
df.head ()
学号班级姓名性别英语体育军训数分高代解几demo
0230802424123080242成龙767877402360及格
1230802424423080242周怡669175474744不及格
2230802425123080242张波858175454560及格
3230802424923080242朱浩655080726271良好
4230802421923080242封印738892614746不及格

上面代码中 bins 有个“坑点”:最大值的取法,即 max(df. 解几)+1中要有一个大于前一个数 (80),否则会提示出错。如本例中最大的分值为84,若设置 bins 为 bins=[min(df.解几)-1,60,70,80,90,max(df.解几)+1],貌似“不及格”“及格”“中等”“良好”“优秀”都齐了,但是会报错,因为最后一项“max(df解几)+1”其实等于 84+1,也就是85,比前一项90小,这不符合单调递增原则。遇到这种情况,最好先把最大值和最小值求出来,再分段。

2.5.10 日期处理

1. 日期转换

日期转换是指将字符型的日期格式转换为日期格式数据的过程。
其命令格式如下:

to_datetime(dateString ,format)

其中, format格式有:

  • %Y :年份;
  • %m :月份;
  • %d : 日期;
  • %H :小时伞;
  • %M :分钟;
  • %S :秒。
【例2-37】to_datetime df:注册时间,format=’%Y/%m%d。
示例代码如下:
from pandas import read_csv
from pandas import to_datetime
df = read_csv ('rz3.csv', sep=',',encoding='utf8')
df
Unnamed: 0numpr iceyearmonthdate
00123159201612016/6/1
11124753201622016/6/2
22125456201 632016/6/3
33126852201 642016/6/4
44127210201652016/6/5
55115299201 662016/6/6
66102699201672016/6/7
77201599201682016/6/8
88154199201692016/6/9
991428992016102016/6/10
2. 日期格式化
【例2-38 】日期型数据转化为字符型数据。
示例代码如下:
from pandas import read_csv
from pandas import to_datetime 
from datetime import datetime

# df_dt = to_datetime (df.注册时间,format='%Y/%m/%d');
# df_dt_str = df_dt.apply(df.注册时间, format='%Y/%m/%d')
 
df = read_csv('rz3.csv', sep=',',encoding='utf8')
df_dt =to_datetime(df.date, format="%Y/%m/%d")
df_dt_str=df_dt.apply(lambda x: datetime.strftime (x, "%Y/%m/%d"))#apply用法见下面的注意提示
df_dt_str

0    2016/06/01
1    2016/06/02
2    2016/06/03
3    2016/06/04
4    2016/06/05
5    2016/06/06
6    2016/06/07
7    2016/06/08
8    2016/06/09
9    2016/06/10
Name: date, dtype: object
3. 日期抽取

日期抽取是指从日期格式里面抽取出需要的部分属性。其命令格式如下:

data dt.dt.property

其中:
其中,property有:

  • second 表示1~60秒,从1开始到60;
  • minute 表示1~60分,从1开始到60;
  • hour表示1~24小时,从1开始到24;
  • day表示1~31日,一个月中第几天,从1开始到31;
  • month 表示1~12月,从1开始到12;
  • year表示年份;
  • weekday表示1~7,一周中的第几天,从1开始,最大为7。
【例2-39 ]对日期进行抽取。
示例代码如下:
from pandas import read_csv;
from pandas import to_datetime;
df = read_csv('rz3.csv', sep=',',encoding='utf8')
df
Unnamed: 0numpr iceyearmonthdate
00123159201612016/6/1
11124753201622016/6/2
22125456201 632016/6/3
33126852201 642016/6/4
44127210201652016/6/5
55115299201 662016/6/6
66102699201672016/6/7
77201599201682016/6/8
88154199201692016/6/9
991428992016102016/6/10
df_dt =to_datetime (df.date,format='%Y/%m/%d')
df_dt
0   2016-06-01
1   2016-06-02
2   2016-06-03
3   2016-06-04
4   2016-06-05
5   2016-06-06
6   2016-06-07
7   2016-06-08
8   2016-06-09
9   2016-06-10
Name: date, dtype: datetime64[ns]
df_dt.dt.year
0    2016
1    2016
2    2016
3    2016
4    2016
5    2016
6    2016
7    2016
8    2016
9    2016
Name: date, dtype: int64
df_dt.dt.day
0     1
1     2
2     3
3     4
4     5
5     6
6     7
7     8
8     9
9    10
Name: date, dtype: int64
df_dt.dt.month 
df_dt.dt.weekday 
df_dt.dt.second 
df_dt.dt.hour
0    0
1    0
2    0
3    0
4    0
5    0
6    0
7    0
8    0
9    0
Name: date, dtype: int64
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值