Pandas

Pandas 是一个开源的第三方库,为 Python 提供高性能、易于使用的数据结构和数据分析工具。

版本

[1]:
import pandas
pandas.__version__
[1]:
'0.24.1'

别名

遵循惯例,使用pd作为别名导入 Pandas.

[2]:
import pandas as pd

数据结构

Pandas 中的数据结构可以看成增强版的 Numpy 数组,主要介绍序列(Series)、数据框(DataFrame)。

序列(Series)

Pandas 中的 Series 对象一种带索引数据构成的一维数组,通过pd.Series()方法创建

[3]:
# 生成一个值为 [1,2,3,4,5] 的 Series 对象
data1 = pd.Series([1, 2, 3, 4, 5])
data1
[3]:
0    1
1    2
2    3
3    4
4    5
dtype: int64

Series 有两个基本属性:indexvalues。其中values储存数组的值,index储存索引数据,默认为[0,1,2,...]递增的整数序列,可通过index=变量指定索引。

[4]:
# 生产一个索引为 [‘a','b','c','d','e'],值为 [1,2,3,4,5] 的 Series 对象
data2 = pd.Series(data=[1,2,3,4,5], index=['a','b','c','d','e'])
data2
[4]:
a    1
b    2
c    3
d    4
e    5
dtype: int64

通过字典(dict)对象也能创建 Series:

[5]:
# 生产一个索引为 [‘a','b','c','d','e'],值为[ 1,2,3,4,5] 的 Series 对象
data3 = pd.Series({'a':1, 'b':2, 'c':3, 'd':4, 'e':5})
data3
[5]:
a    1
b    2
c    3
d    4
e    5
dtype: int64

数据框(DataFrame)

Pandas 中的 DataFrame 对象可以看成多个相同索引的 Series 对象组成的数据类型,同时具有行索引和列索引,类似 Excel 中的表格,通过pd.DataFrame()方法创建

[6]:
# 将 data2、data3合并为一个 DataFrame 对象
Data = pd.DataFrame({"data2":data2, "data3":data3})
Data
[6]:
data2 data3
a 1 1
b 2 2
c 3 3
d 4 4
e 5 5

数据文件的输出和输入

Pandas 可以直接从xlsx、csv等文件中输入数据,也可以将数据输出到xlsx、csv等文件中。

文件输入

常用方法

  • pd.read_csv():从文件、URL、文件型对象中加载带分隔符的数据,默认分隔符为逗号。

  • pd.read_excel():从EXCLE的xls文件中加载数据。

[7]:
# 导入 iris.csv
iris = pd.read_csv('./data/iris.csv')

# 显示前五行
iris.head()
[7]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa

文件导出

Pandas 中的文件导出操作与文件导入操作类似,常用方法有pd.to_csv()pd.to_excel

[8]:
iris.to_csv('./data/iris_1.csv')

Iris = pd.read_csv('./data/iris_1.csv')
Iris.head()
[8]:
Unnamed: 0 sepal_length sepal_width petal_length petal_width species
0 0 5.1 3.5 1.4 0.2 setosa
1 1 4.9 3.0 1.4 0.2 setosa
2 2 4.7 3.2 1.3 0.2 setosa
3 3 4.6 3.1 1.5 0.2 setosa
4 4 5.0 3.6 1.4 0.2 setosa

中文编码问题

利用 Pandas 导入、导出含中文字符的数据文件时,有可能出现中文字符无法正常识别的问题,如果按默认格式导入数据的话,容易报错UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb1 in position 0: invalid start byte,这时候就需要使用encoding变量

# 按照默认格式导入 data.csv 文件
watermelon = pd.read_csv('./data/watermelon.csv')

# UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb1 in position 0: invalid start byte
[9]:
# 导入 data.csv 文件
watermelon = pd.read_csv('./data/watermelon.csv',encoding = 'gb2312')
watermelon.head()
[9]:
编号 色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜
0 No01 青绿 蜷缩 浊响 清晰 凹陷 硬滑 0.697 0.460
1 No02 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 0.774 0.376
2 No03 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 0.634 0.264
3 No04 青绿 蜷缩 沉闷 清晰 凹陷 硬滑 0.608 0.318
4 No05 浅白 蜷缩 浊响 清晰 凹陷 硬滑 0.556 0.215

索引与切片

由于 Pandas 中的数据结构引入的行索引和列索引,故在 Python 和 Numpy 中利用中括号[]进行索引的操作在 Pandas 中已无法使用,在 Pandas 中可以通过pd.loc[]pd.iloc[]进行索引和切分操作。

区别:

  • pd.loc[]:利用数据文件中自带的标签索引数据;

  • pd.iloc[]: 利用数据文件中的行号与列号索引数据,与在 Python 和 Numpy 中利用中括号[]进行索引类似;

[10]:
# 导入 data.csv 文件,利用编号列进行行索引
watermelon = pd.read_csv('./data/watermelon.csv', encoding = 'gb2312', index_col = '编号')
watermelon.head()
[10]:
色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜
编号
No01 青绿 蜷缩 浊响 清晰 凹陷 硬滑 0.697 0.460
No02 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 0.774 0.376
No03 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 0.634 0.264
No04 青绿 蜷缩 沉闷 清晰 凹陷 硬滑 0.608 0.318
No05 浅白 蜷缩 浊响 清晰 凹陷 硬滑 0.556 0.215
[11]:
# 利用 pd.loc[]
print(watermelon.loc['No01':'No04', '色泽':'触感'])
print('---------------------------------------')

# 利用 pd.iloc[]
print(watermelon.iloc[:4, :6])
      色泽  根蒂  敲声  纹理  脐部  触感
编号
No01  青绿  蜷缩  浊响  清晰  凹陷  硬滑
No02  乌黑  蜷缩  沉闷  清晰  凹陷  硬滑
No03  乌黑  蜷缩  浊响  清晰  凹陷  硬滑
No04  青绿  蜷缩  沉闷  清晰  凹陷  硬滑
---------------------------------------
      色泽  根蒂  敲声  纹理  脐部  触感
编号
No01  青绿  蜷缩  浊响  清晰  凹陷  硬滑
No02  乌黑  蜷缩  沉闷  清晰  凹陷  硬滑
No03  乌黑  蜷缩  浊响  清晰  凹陷  硬滑
No04  青绿  蜷缩  沉闷  清晰  凹陷  硬滑

通用方法

Pandas 中常用的统计函数:

统计函数

描述

pd.count()

统计个数,空值NaN不计算

pd.min()

最小值

pd.max()

最大值

pd.sum()

求和

pd.mean()

均值

pd.median()

中位数

pd.var()

方差

pd.std()

标准差

pd.idxmin()

最小值的索引位置

pd.idxmax()

最小值的索引位置

Pandas 中的通用方法:

通用方法

描述

pd.head(n=5)

返回 DataFrame 的前 n 行数据

pd.tial(n=5)

返回 DataFrame 的后 n 行数据

pd.info()

返回 DataFrame 的简明摘要

pd.describe()

返回 DataFrame 的描述性统计数据

pd.drop()

删除 DataFrame 中的不必要的列或行

pd.drop_duplicates(subset=None)

删除 DataFrame 中重复行,可通过subset变量选择筛选列

[12]:
# 返回 Iris 的前五行
print('Iris.head() = \n',Iris.head())
print('-'*60)

# 返回 Iris 的后五行
print('Iris.tail() = \n',Iris.tail())
print('-'*60)

# 返回 Iris 的简明摘要
print(Iris.info())
print('-'*60)

# 返回 Iris 的描述性统计数据
print('Iris.describe() = \n',Iris.describe())
print('-'*60)

# 删除 Iris 中的 Unnamed 列
print('Iris.drop() = \n',Iris.drop(columns=['Unnamed: 0']).head())
print('-'*60)
Iris.head() =
    Unnamed: 0  sepal_length  sepal_width  petal_length  petal_width species
0           0           5.1          3.5           1.4          0.2  setosa
1           1           4.9          3.0           1.4          0.2  setosa
2           2           4.7          3.2           1.3          0.2  setosa
3           3           4.6          3.1           1.5          0.2  setosa
4           4           5.0          3.6           1.4          0.2  setosa
------------------------------------------------------------
Iris.tail() =
      Unnamed: 0  sepal_length  sepal_width  petal_length  petal_width  \
145         145           6.7          3.0           5.2          2.3
146         146           6.3          2.5           5.0          1.9
147         147           6.5          3.0           5.2          2.0
148         148           6.2          3.4           5.4          2.3
149         149           5.9          3.0           5.1          1.8

       species
145  virginica
146  virginica
147  virginica
148  virginica
149  virginica
------------------------------------------------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 6 columns):
Unnamed: 0      150 non-null int64
sepal_length    150 non-null float64
sepal_width     150 non-null float64
petal_length    150 non-null float64
petal_width     150 non-null float64
species         150 non-null object
dtypes: float64(4), int64(1), object(1)
memory usage: 7.1+ KB
None
------------------------------------------------------------
Iris.describe() =
        Unnamed: 0  sepal_length  sepal_width  petal_length  petal_width
count  150.000000    150.000000   150.000000    150.000000   150.000000
mean    74.500000      5.843333     3.057333      3.758000     1.199333
std     43.445368      0.828066     0.435866      1.765298     0.762238
min      0.000000      4.300000     2.000000      1.000000     0.100000
25%     37.250000      5.100000     2.800000      1.600000     0.300000
50%     74.500000      5.800000     3.000000      4.350000     1.300000
75%    111.750000      6.400000     3.300000      5.100000     1.800000
max    149.000000      7.900000     4.400000      6.900000     2.500000
------------------------------------------------------------
Iris.drop() =
    sepal_length  sepal_width  petal_length  petal_width species
0           5.1          3.5           1.4          0.2  setosa
1           4.9          3.0           1.4          0.2  setosa
2           4.7          3.2           1.3          0.2  setosa
3           4.6          3.1           1.5          0.2  setosa
4           5.0          3.6           1.4          0.2  setosa
------------------------------------------------------------

数据透视表

通过数据透视表可以探究数据集内部的关联性,在 Pandas 可以通过pd.groupby()pd.pivot_table()方法实现。

[13]:
# 导入 titanic
titanic =pd.read_csv('./data/titanic.csv')

titanic.head()
[13]:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S

统计不同性别、不同船舱乘客的生还率:

[14]:
# 通过 pd.groupby() 方法
print('titanic.groupby =\n',titanic.groupby(['Sex', 'Pclass'])['Survived'].aggregate('mean').unstack())
print('-'*30)

# 通过 pd.pivot_table() 方法
print('titanic.pivot_table =\n',titanic.pivot_table('Survived', index='Sex', columns='Pclass'))
titanic.groupby =
 Pclass         1         2         3
Sex
female  0.968085  0.921053  0.500000
male    0.368852  0.157407  0.135447
------------------------------
titanic.pivot_table =
 Pclass         1         2         3
Sex
female  0.968085  0.921053  0.500000
male    0.368852  0.157407  0.135447

pd.groupby()方法相比,pd.pivot_table()方法更简洁,建议使用后者。