Pandas¶
Pandas 是一个开源的第三方库,为 Python 提供高性能、易于使用的数据结构和数据分析工具。
数据结构¶
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 有两个基本属性:index
和 values
。其中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() |
统计个数,空值 |
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 中重复行,可通过 |
[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()
方法更简洁,建议使用后者。