利用Python进行数据分析-Pandas:
在Pandas库中最重要的两个数据类型,分别是Series和DataFrame。如下的内容主要围绕这两个方面展开叙述!
在进行数据分析时,我们知道有两个基础的第三方库在数据处理时显得尤为重要,即分别为NumPy库和Pandas库,前面的章节我们对于NumPy的入门有了详细的介绍,这个章节我们主要是对于Pandas库进行系统的总结。说一点题外话,之前对于学习知识的时候,基本上都是在网上看视频,但是看视频的时候,当时基本上都能够理解并且觉得很简单,也没有对于知识点做一个笔记,以致后来慢慢忘记很多的内容,俗话说得好,好记性不如烂笔头,所以自己尽量会把以后学的知识点记录在博客上,这样以后方便知识点的查询。
本编文章所使用的环境:
python:3.6.6 编译器:pycharm 操作系统:win10
一、Series
1、Series的结构:
series类型由一组数据及与之相关的数据索引组成:
举例说明:
import pandas as pd a = pd.Series([9, 8, 7, 6]) print(a)
0 9 1 8 2 7 3 6 dtype: int64
从以上结果,我们可以看到Pandas库会自动给数据增加索引!但是我们可以提供自定义索引,使用index参数可提供索引值:
import pandas as pd b = pd.Series([9, 8, 7, 6], index=['a', 'b', 'c', 'd']) print(b)
a 9 b 8 c 7 d 6 dtype: int64
以上我们可以看到数据的索引已经变更为我们提供的索引值!
2、Series类型的创建:
- 可以由python列表创建;
- 可以由标量值(一个值)创建;
- 可以由python字典创建;
- 可以由ndarray创建;
- 可以通过其他函数创建。
举例说明:
从标量值创建:当使用标量值创建的时候,index是不能被省略的:
import pandas as pd s = pd.Series(25, index=['a', 'b', 'c']) print(s)
a 25 b 25 c 25 dtype: int64
从字典类型创建:
import pandas as pd d = pd.Series({'a': 9, 'b': 8, 'c': 7}) print(d)
a 9 b 8 c 7 dtype: int64
另外:在使用字典创建时,索引值可以根据index来选择操作:
import pandas as pd e = pd.Series({'a': 9, 'b': 8, 'c': 7}, index=['c', 'a', 'b', 'd']) print(e)
c 7.0 a 9.0 b 8.0 d NaN dtype: float64
当索引值无对应值时,显示为NaN。
从ndarray类型创建:当不提供index时,series会提供自动索引
import pandas as pd import numpy as np n = pd.Series(np.arange(5)) print(n)
0 0 1 1 2 2 3 3 4 4 dtype: int32
从ndarray类型创建:当提供index时,series使用提供的索引
import pandas as pd import numpy as np m = pd.Series(np.arange(5), index=np.arange(9, 4, -1)) print(m)
9 0 8 1 7 2 6 3 5 4 dtype: int32
3、Series类型的基本操作
series类型包括index和values两部分:其实对于series的操作理论上是对于index和values的操作:
举例说明:首先创建一个series类型
import pandas as pd b = pd.Series([9, 8, 7, 6], ['a', 'b', 'c', 'd']) print(b)
a 9 b 8 c 7 d 6 dtype: int64
series类型的索引值:如下使用.index方法
print(b.index)
Index(['a', 'b', 'c', 'd'], dtype='object')
series类型的数据:如下使用.values方法
print(b.values)
[9 8 7 6]
另外,对于值的引用可以使用切片的形式:
print(b['b'])
8
print(b[1])
8
二、DataFrame
DataFrame是一个表格型的数据结构,它含有一组有序数列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看作由Series组成的字典(共用同一个索引)。DataFrame中的数据是以一个或多个二维块存放(而不是列表、字典或别的一维数据结构)。DataFrame常用于表达二维数据,但可以表达多维数据。
DataFrame类型可以由以下类型创建:
- 二维ndarray对象;
- 由一维ndarray、列表、字典、元组或Series构成的字典;
- Series类型;
- 其他的DataFrame类型。
创建DataFrame的办法有很多,最常用的一种是直接传入一个等长列表或NumPy数组组成字典:(举例来源Python for Data Analysis)
import pandas as pd data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002, 2003], 'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]} frame = pd.DataFrame(data) print(frame)
state year pop 0 Ohio 2000 1.5 1 Ohio 2001 1.7 2 Ohio 2002 3.6 3 Nevada 2001 2.4 4 Nevada 2002 2.9 5 Nevada 2003 3.2
结果DataFrame会自动加上索引,且全部列会被有序排列。
对于特别大的DataFrame,使用head方法可以选取前五行:
print(frame.head())
state year pop 0 Ohio 2000 1.5 1 Ohio 2001 1.7 2 Ohio 2002 3.6 3 Nevada 2001 2.4 4 Nevada 2002 2.9
如果指定了列序列,则DataFrame的列就会按照顺序进行排列:
print(pd.DataFrame(data, columns=['year', 'state', 'pop']))
year state pop 0 2000 Ohio 1.5 1 2001 Ohio 1.7 2 2002 Ohio 3.6 3 2001 Nevada 2.4 4 2002 Nevada 2.9 5 2003 Nevada 3.2
如果传入的列在数据中找不到,就会在结果中产生缺失值:
frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'], index=['one', 'two', 'three', 'four', 'five', 'six']) print(frame2)
year state pop debt one 2000 Ohio 1.5 NaN two 2001 Ohio 1.7 NaN three 2002 Ohio 3.6 NaN four 2001 Nevada 2.4 NaN five 2002 Nevada 2.9 NaN six 2003 Nevada 3.2 NaN
通过属性可以直接获取DataFrame的行和列:
print(frame2.columns) print(frame2.index)
Index(['year', 'state', 'pop', 'debt'], dtype='object') Index(['one', 'two', 'three', 'four', 'five', 'six'], dtype='object')
通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series:
print(frame2['state'])
one Ohio two Ohio three Ohio four Nevada five Nevada six Nevada Name: state, dtype: object
可以查看获得的列的数据类型:
print(type(frame2['state']))
<class 'pandas.core.series.Series'>
行也可以通过位置或名称的方式进行获取,比如用loc属性:
print(frame2.loc['three'])
year 2002 state Ohio pop 3.6 debt NaN Name: three, dtype: object
列可以通过赋值的方式进行修改。例如,我们可以给那个空的"debt"列赋上一个标量值或一组值:
frame2['debt'] = 16.5 print(frame2)
year state pop debt one 2000 Ohio 1.5 16.5 two 2001 Ohio 1.7 16.5 three 2002 Ohio 3.6 16.5 four 2001 Nevada 2.4 16.5 five 2002 Nevada 2.9 16.5 six 2003 Nevada 3.2 16.5
或者使用np.range赋值:
frame2['debt'] = np.arange(6) print(frame2)
year state pop debt one 2000 Ohio 1.5 0 two 2001 Ohio 1.7 1 three 2002 Ohio 3.6 2 four 2001 Nevada 2.4 3 five 2002 Nevada 2.9 4 six 2003 Nevada 3.2 5
将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值。
val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five']) frame2['debt'] = val print(frame2)
year state pop debt one 2000 Ohio 1.5 NaN two 2001 Ohio 1.7 -1.2 three 2002 Ohio 3.6 NaN four 2001 Nevada 2.4 -1.5 five 2002 Nevada 2.9 -1.7 six 2003 Nevada 3.2 NaN
为不存在的列赋值会创建出一个新列。关键字del用于删除列。
作为del的例子,先添加一个新的布尔值的列:
frame2['eastern'] = frame2.state == 'Ohio' print(frame2)
year state pop debt eastern one 2000 Ohio 1.5 NaN True two 2001 Ohio 1.7 -1.2 True three 2002 Ohio 3.6 NaN True four 2001 Nevada 2.4 -1.5 False five 2002 Nevada 2.9 -1.7 False six 2003 Nevada 3.2 NaN False
注意:不能用frame2.eastern创建新的列!
在这里,我们可以使用del方法来删除这列:
del frame2['eastern'] print(frame2.columns)
Index(['year', 'state', 'pop', 'debt'], dtype='object')
注意:通过索引方式返回的列只是相应数据的视图而已,并不是副本。因此,对返回的Series所做的任何就地修改全都会反映到源DataFrame上。通过Series的copy方法即可指定复制列。
另一种常见的数据形式是嵌套字典:
pop = {'Nevada': {2001: 2.4, 2002: 2.9}, 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}} frame3 = pd.DataFrame(pop) print(frame3)
Nevada Ohio 2001 2.4 1.7 2002 2.9 3.6 2000 NaN 1.5
如果嵌套字典传给DataFrame,Pandas就会被解释为:外层字典的键作为列,内层键则作为行索引!
也可以使用类似NumPy数组的方法,对DataFrame进行转置:
print(frame3.T)
2001 2002 2000 Nevada 2.4 2.9 NaN Ohio 1.7 3.6 1.5
内层字典的键会被合并、排序以形成最终的索引。如果明确指定了索引,则不会这样:
print(pd.DataFrame(pop, index=[2001, 2002, 2003]))
Nevada Ohio 2001 2.4 1.7 2002 2.9 3.6 2003 NaN NaN
如下表列出了DataFrame构造函数所能接受的各种数据:
二维ndarray | 数据矩阵,还可以行标和列标 |
由数组、列标或元组组成的字典 | 每个序列会变成DataFrame的一列。所有序列的长度必须相同 |
NumPy的结构化/记录数组 | 类似于“由数组组成的字典” |
由Series组成的字典 | 每个Series会成为一列。如果没有显示指定索引,则各Series的索引会被合并成结果的行索引 |
由字典组成的字典 | 各内层字典会成为一列。键会被合并成结果的行索引,跟“由Series组成的字典”的情况一样 |
字典或Series的列表 | 各项将会成为DataFrame的一行。字典键或Series索引的并集会成为DataFrame的列标。 |
由列表或元组组成的列表 | 类似于“二维ndarray” |
另一个DataFrame | 该DataFrame的索引将会被引用,除非显示指定了其他索引 |
NumPy的MaskedArray | 类似于“二维ndarray”的情况,只是掩码值在结果DataFrame会变成NA/缺失值 |
如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来:
frame3.index.name = 'year' frame3.columns.name = 'state' print(frame3)
state Nevada Ohio year 2001 2.4 1.7 2002 2.9 3.6 2000 NaN 1.5
跟Series一样,values属性也会以二维ndarray的形式返回DataFrame中的数据:
print(frame3.values)
[[2.4 1.7] [2.9 3.6] [nan 1.5]]
如果DataFrame各列的数据类型不同,则值数组的dtype就会选用能兼容所有列的数据类型:
print(frame2.values)
[[2000 'Ohio' 1.5 nan] [2001 'Ohio' 1.7 -1.2] [2002 'Ohio' 3.6 nan] [2001 'Nevada' 2.4 -1.5] [2002 'Nevada' 2.9 -1.7] [2003 'Nevada' 3.2 nan]]
索引对象:
pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等)。构建Series或DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个index:
import pandas as pd obj = pd.Series(range(3), index=['a', 'b', 'c']) index = obj.index print(index) print(index[1:])
Index(['a', 'b', 'c'], dtype='object') Index(['b', 'c'], dtype='object')
Index对象是不可变的,因此用户不能对其进行修改!
除了类似于数组,Index的功能也类似一个固定大小的集合:
import pandas as pd pop = {'Nevada': {2001: 2.4, 2002: 2.9}, 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}} frame3 = pd.DataFrame(pop) print(frame3)
state Nevada Ohio year 2001 2.4 1.7 2002 2.9 3.6 2000 NaN 1.5
print(frame3.columns)
Index(['Nevada', 'Ohio'], dtype='object', name='state')
可以使用in关键字来判断index是否存在集合中:
print('Ohio' in frame3.columns) print(2003 in frame3.index)
True False
与python的集合不同,pandas的index可以包含重复的标签!
对于index如下列表是index的方法和属性!
append | 连接另一个index对象,产生一个新的index |
difference | 计算差集,并得到一个index |
intersection | 计算交集 |
union | 计算并集 |
isin | 计算一个指示各值是否都包含在参数集合中的布尔型数组 |
delete | 删除索引i处的元素,并得到新的index |
drop | 删除传入的值,并得到新的index |
insert | 将元素插入到索引i处,并得到新的index |
is_monotonic | 当各元素均大于等于前一个元素时,返回True |
is_unique | 当index没有重复值时,返回True |
unique | 计算index中唯一值的数组 |