Series&DataFrame
1. 概述
众所周知,数据分析三剑客:numpy,pandas,matplotlib。之前的文章介绍了numpy中的使用,接下来将进入pandas的领域。首先要对numpy和pandas进行一定的区分,两者都是针对数据处理而诞生的库,但是各有侧重,numpy主要针对多维数值型矩阵的处理,而pandas针对的是日常生活中如excel表类似的关系型二维矩阵的处理。
2. Series
2.1 Series的构建
2.1.1从数组的角度
Series可以理解为索引不强制为 0 − n 0-n 0−n的数组,通常构建一个series可以用以下方式:
pd.series([内容数组],index=[索引数组])
如果没有索引数组,则默认与数组一致的 0 − n 0-n 0−n,如下例子:
obj = pd.Series([4, 7, -5, 3])
'''0 4
1 7
2 -5
3 3
dtype: int64'''
obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
'''d 4
b 7
a -5
c 3
dtype: int64'''
需要注意的是,即便设置了自定义的index,你依旧可以使用原生数组中的 0 − n 0-n 0−n进行索引和切片。
2.1.2 从字典的角度
可以看出,series已经弱化了传统数组一维的概念,更加强化了字典中所强调的对应关系,因此也可理解成index-value的对应。pandas也提供了使用python原生字典进行构造series的方式,如下例子所示:
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = pd.Series(sdata)
obj3
'''Ohio 35000
Texas 71000
Oregon 16000
Utah 5000
dtype: int64'''
python原生的字典实际上是无序的,如果希望对应的index顺序需要改变,可以对构造函数中的index变量进行设置,如下例所示:
states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = pd.Series(sdata, index=states)
obj4
'''
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
'''
同样的,既然类似与原生字典类型,也可以用in操作判定。
2.2 Series的索引与操作
索引和一些简单的操作很杂也很相似,很难做出明确的区分,因此就统一来讲。
- 首先就是索引,其索引方式和字典类似,利用Series.index即可返回索引列表(需要注意的是,1、创建后的index是不允许改变的;2、index中可以有重复元素存在),利用Series.values即可返回值Series[key]就可索引到对应的内容,同时也兼具了numpy中的特性,利用Series[[多个key]]可以完成多组返回,利用Series[布尔表达]也可返回对应value为True的结果,如下例所示:
obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
obj2[obj2 > 0]
obj2[obj2.index>'a']
'''
d 4
b 7
c 3
dtype: int64
'''
'''
d 4
b 7
c 3
dtype: int64
'''
- 同时,也可对Series整体完成操作,如加减乘除, e x e^x ex等操作,如下例:
obj2+1
obj2 * 2
np.exp(obj2)
'''
d 5
b 8
a -4
c 4
dtype: int64
'''
'''
d 8
b 14
a -10
c 6
dtype: int64
'''
'''
d 54.598150
b 1096.633158
a 0.006738
c 20.085537
dtype: float64
'''
- 同样的,既然类似与原生字典类型,也可以用in操作判定。
- 需要注意的是,在pandas完成创建后,会出现缺失值,即NA,利用isnull或者notnull函数可以完成对缺失值的判定。这在之后的清理数据过程中极为重要!
'''针对obj4:
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
'''
pd.isnull(obj4)
pd.notnull(obj4)
obj4.isnull()
'''
California True
Ohio False
Oregon False
Texas False
dtype: bool
###################
California False
Ohio True
Oregon True
Texas True
dtype: bool
###################
California True
Ohio False
Oregon False
Texas False
dtype: bool
'''
- 两个数组也可进行操作,在这过程中完成对齐这一特性,该特性及其类似于并集:
obj3
obj4
obj3 + obj4
'''
Ohio 35000
Texas 71000
Oregon 16000
Utah 5000
dtype: int64
#####################
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
######################
California NaN
Ohio 70000.0
Oregon 32000.0
Texas 142000.0
Utah NaN
dtype: float64
'''
- Series的自身和index都有name属性,注意:values并无name属性!
obj4.name = 'population'
obj4.index.name = 'state'
obj4
'''
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64
'''
- 可以通过对index赋值完成对index的更改,value的更改可以利用索引更改:
obj
obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
obj
'''
0 4
1 7
2 -5
3 3
dtype: int64
#############
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64
'''
3.DataFrame
pandas最为重要的部分,DataFrame,你可以简单的理解成一张二维表,就像Excel一样,如果从底层的角度,可以理解成多个Series的组合,但是这些Series共享一个index。笔者还是建议直接理解成Excel,更贴近使用场景。
3.1 DataFrame的构造
DataFrame的构成可以拆解成index,value,colums
这种设计非常顺应直觉,正常的excel或者数据也是一样的设计
DataFrame具有多种构造方式,如下所示:
- 利用字典或者列表即可:
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)
'''
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
'''
同样的,在构造的过程中也可以通过设置index,columns参数调整顺序,也可访问相应的属性。如果原数据中并没有column中要求的列,会出现整列的NaN数据。
data
frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
index=['one', 'two', 'three', 'four',
'five', 'six'])
frame2
frame2.columns
- 嵌套字典
利用{列名:{行名(索引值):值,行名(索引值):值}}形式的两层嵌套字典也可以完成
3.2 DataFrame索引与切片
- 利用DataFrame[‘列名’]或者DataFrame.列名可以完成对于某一列的读取,其返回为一个Series,其索引和DataFrame具有一致的索引。
- 使用DataFrame.列名的方式对列名是有一定要求的,要求列名符合python变量命名方式。还需要注意的是,DataFrame[‘列名’]如果列名不存在,会自己创建,而DataFrame.列名并不会
- 需要注意的是,这里的索引结果和numpy中的视图一致,对索引之后的Series做出的任何操作都会直接反应到原DataFrame上,如果要复制则需要使用copy方法。
- 利用DataFrame.loc[‘index’]可以读取到一整行的数据。
3.3 DataFrame的操作
- 赋值
当使用python原生数组完成赋值的时候,要求其长度必须匹配,但是如果使用Series,则会根据索引完成匹配,若是空的地方就填入Nan,但是对于index不存在原数据的情况,并不会增加index的长度:
frame2
val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'seven'])
frame2['debt'] = val
frame2
- 删除
利用del关键字就可以完成删除操作。
-属性
可以利用.index.属性,.columns.属性,.values等方法提取相关属性。