Python数据分析之pandas的数据结构

1、Series

(1)简介

Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。仅由一组数据即可产生最简单的Series:

obj = pd.Series([4,7,-5,3])

obj
Out[16]: 
0    4
1    7
2   -5
3    3
dtype: int64

(2)Series的字符串表现形式为:索引在左,值在右边

由于我们没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的长度)的整数型索引。你可以通过Series的valuesindex属性获取其数组表示形式和索引对象:

obj.values
Out[17]: array([ 4,  7, -5,  3], dtype=int64)
obj.index
Out[19]: RangeIndex(start=0, stop=4, step=1)

(3)通常,我们希望所创建的Series带有一个可以对各个数据点进行标记的索引:

obj2 = pd.Series([4,7,-5,3],index=['d','F','W','f'])
obj2
Out[4]: 
d    4
F    7
W   -5
f    3
dtype: int64

obj2.index
Out[5]: Index(['d', 'F', 'W', 'f'], dtype='object')

与普通NumPy数组相比,你可以通过索引的方式选取Series中的单个或一组值:

obj2['d']
Out[7]: 4

obj2['d'] = 6

obj2[['d','F','W']]
Out[9]: 
d    6
F    7
W   -5
dtype: int64

(4)NumPy数组运算(如根据布尔型数组进行过滤、标量乘法、应用数学函数等)都会保留索引和值之间的链接:

obj2
Out[10]: 
d    6
F    7
W   -5
f    3
dtype: int64

obj2[obj2 > 0]
Out[11]: 
d    6
F    7
f    3
dtype: int64

obj2 * 2
Out[12]: 
d    12
F    14
W   -10
f     6
dtype: int64

np.exp(obj2)
Out[15]: 
d     403.428793
F    1096.633158
W       0.006738
f      20.085537
dtype: float64

(5)可以将Series看成是一个定长的有序字典,因为它是索引值到数据值的一个映射。它可以用在许多原本需要字典参数的函数中:

'b' in obj2
Out[16]: False

'd' in obj2
Out[17]: True

如果数据被存放在一个Python字典中,也可以直接通过这个字典来创建Series:

data = {'a':23,'T':45,'S':34}
obj3 = pd.Series(data)
obj3
Out[22]: 
a    23
T    45
S    34
dtype: int64

如果只传入一个字典,则结果Series中的索引就是原字典的键(有序排列)。

import pandas as pd
sdata = {'sa':23,'sfq':45,'dsa':75}
obj3 = pd.Series(sdata)
print(obj3)
sa     23
sfq    45
dsa    75
dtype: int64

states = ['sa','hh','dsa','sfq']
obj4 = pd.Series(sdata,index = states)
obj4
Out[4]: 
sa     23.0
hh      NaN
dsa    75.0
sfq    45.0
dtype: float64

在这个例子中,sdata中跟states索引相匹配的那3个值会被找出来并放到相应的位置上,但由于“hh”所对应的sdata值找不到,所以其结果就为NaN(即‘not a number’,在pandas中,它用于表示缺失或NA值。在这里会使用missing或NA表示缺失数据)。pandasisnullnotnull函数可用于检测缺失数据:

pd.isnull(obj4)
Out[5]: 
sa     False
hh      True
dsa    False
sfq    False
dtype: bool

pd.notnull(obj4)
Out[6]: 
sa      True
hh     False
dsa     True
sfq     True
dtype: bool

Series也有类似的实例方法:

obj4.isnull()
Out[7]: 
sa     False
hh      True
dsa    False
sfq    False
dtype: bool

(6)对于应用而言,Series最重要的一个功能是:它在算术运算中会自动对齐不同索引的数据

obj3
Out[8]: 
sa     23
sfq    45
dsa    75
dtype: int64

obj4
Out[9]: 
sa     23.0
hh      NaN
dsa    75.0
sfq    45.0
dtype: float64

obj3+obj4
Out[10]: 
dsa    150.0
hh       NaN
sa      46.0
sfq     90.0
dtype: float64

(7)Series对象本身及其索引都有一个name属性,该属性跟pandas其他的关键功能关系非常密切:

obj4.name='population'
obj4.index.name = 'state'
obj4
Out[13]: 
state
sa     23.0
hh      NaN
dsa    75.0
sfq    45.0
Name: population, dtype: float64

Series的索引可以通过赋值的方式就地修改:

obj4.index = ['Bob','Ss','sw','ww']        #对的
obj4.index = ['Bob','Ss','sw','ww','fwq']  #错的,个数与原Series不符

2、DataFrame

(1)DataFrame简介

DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看作由Series组成的字典(共用同一个索引)。跟其他类似的数据结构相比(如R的data.frame),DataFrame中面向行和面向列的操作基本上是平衡的。其实,DataFrame中的数据是以一个或多个二维块存放的(而不是列表、字典或别的一维数据结构)。

(2)构建DataFrame

构建DataFrame的方法有很多,最常用的一种是直接传入一个由等长列表或NumPy数组组成的字典:

from pandas import Series,DataFrame
data = {'state':['a','b','c','d','e'],
        'year':[200,341,3432,23,43],
        'pop':[1.5,2.4,2.3,4.4,5.5]}
frame = DataFrame(data)

结果DataFrame会自动加上索引(跟Series一样),且全部列会被有序排列:

frame
Out[4]: 
  state  year  pop
0     a   200  1.5
1     b   341  2.4
2     c  3432  2.3
3     d    23  4.4
4     e    43  5.5

如果指定了列序列,则DataFrame的列就会按照指定顺序进行排列:

DataFrame(data,columns=['year','state','pop'])
Out[5]: 
   year state  pop
0   200     a  1.5
1   341     b  2.4
2  3432     c  2.3
3    23     d  4.4
4    43     e  5.5

(3)跟Series一样,如果传入的列在数据中找不到,就会产生NA值:

frame2 = DataFrame(data,columns=['year','state','pop','debt'],index=['one','two','three','four','five'])

frame2
Out[7]: 
       year state  pop debt
one     200     a  1.5  NaN
two     341     b  2.4  NaN
three  3432     c  2.3  NaN
four     23     d  4.4  NaN
five     43     e  5.5  NaN

frame2.columns
Out[8]: Index(['year', 'state', 'pop', 'debt'], dtype='object')

(4)通过类似字典标记的方式属性的方式,可以将DataFrame的获取为一个Series:

frame2.year
Out[9]: 
one       200
two       341
three    3432
four       23
five       43
Name: year, dtype: int64

frame2['state']
Out[10]: 
one      a
two      b
three    c
four     d
five     e
Name: state, dtype: object

注意,返回的Series拥有原DataFrame相同的索引,且其name属性也已经被相应地设置好了。

也可以通过位置或名称的方式进行获取,比如用索引字段ix,没有iy这个东东!

frame2.ix['three']
Out[11]: 
year     3432
state       c
pop       2.3
debt      NaN
Name: three, dtype: object

(5)列可以通过赋值的方式进行修改,例如,我们可以给那个空的“debt”列赋上一个标量值或一组值:

frame2['debt']=2
frame2
Out[13]: 
       year state  pop  debt
one     200     a  1.5     2
two     341     b  2.4     2
three  3432     c  2.3     2
four     23     d  4.4     2
five     43     e  5.5     2

import numpy as np
frame2['debt'] = np.arange(5.)
frame2
Out[16]: 
       year state  pop  debt
one     200     a  1.5   0.0
two     341     b  2.4   1.0
three  3432     c  2.3   2.0
four     23     d  4.4   3.0
five     43     e  5.5   4.0

将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值:

val = Series([-1.2,-1.5,2.3],index=['two','t','five'])    #如果设置的index中,存在和原DataFrame不相同的索引,会忽略
frame2['debt'] = val
frame2
Out[17]: 
       year state  pop  debt
one     200     a  1.5   NaN
two     341     b  2.4  -1.2
three  3432     c  2.3   NaN
four     23     d  4.4   NaN
five     43     e  5.5   2.3

为不存在的列赋值会创建出一个新列。关键字del用于删除列:

frame2['eastern'] = frame2.state=='Oh'
frame2
Out[19]: 
       year state  pop  debt  eastern
one     200     a  1.5   NaN    False
two     341     b  2.4  -1.2    False
three  3432     c  2.3   NaN    False
four     23     d  4.4   NaN    False
five     43     e  5.5   2.3    False

del frame2['eastern']
frame2.columns
Out[20]: Index(['year', 'state', 'pop', 'debt'], dtype='object')

通过索引方式返回的列只是相应数据的视图而已,并不是副本。因此对返回的Series所做的任何就地修改全都会反映到源DataFrame上。通过Series的copy方法即可显式地复制列。

(6)嵌套字典(字典中的字典)

pop = {'aa':{100:3,324:21},'bb':{200:1.5,201:1.7,203:4.5}}

如果将它传给DataFrame,则   外层字典的键作为列,内层键则作为行索引

frame = DataFrame(pop)
frame
Out[21]: 
       aa   bb
100   3.0  NaN
200   NaN  1.5
201   NaN  1.7
203   NaN  4.5
324  21.0  NaN

当然,可以对该结果进行转置:

frame.T
Out[22]: 
    100  200  201  203   324
aa  3.0  NaN  NaN  NaN  21.0
bb  NaN  1.5  1.7  4.5   NaN
DataFrame(pop,index=[100,200,201,203,204])
Out[23]: 
      aa   bb
100  3.0  NaN
200  NaN  1.5
201  NaN  1.7
203  NaN  4.5
204  NaN  NaN

DataFrame(pop,columns=['aa','bb'])
Out[25]: 
       aa   bb
100   3.0  NaN
200   NaN  1.5
201   NaN  1.7
203   NaN  4.5
324  21.0  NaN

由Series组成的字典差不多也是一样的用法:

pdata = {'aa':frame['aa'][:-1],
         'cc':frame['bb'][:2]}

DataFrame(pdata)
Out[27]: 
      aa   cc
100  3.0  NaN
200  NaN  1.5
201  NaN  NaN
203  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的names属性,则这些信息也会被显示出来:

frame.index.name = 'year'
frame.columns.name = 'state'
frame
Out[4]: 
state    aa   bb
year            
100     3.0  NaN
200     NaN  1.5
201     NaN  1.7
203     NaN  4.5
324    21.0  NaN

跟Series一样,values属性也会以二维ndarray的形式返回DataFrame中的数据:

frame.values
Out[5]: 
array([[ 3. ,  nan],
       [ nan,  1.5],
       [ nan,  1.7],
       [ nan,  4.5],
       [21. ,  nan]])

如果DataFrame各列的数据类型不同,则值数组的数据类型就会选用能兼容所有列的数据类型。

3、索引对象

pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等)。构建Series或DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index:

obj = Series(range(3),index=['a','b','c'])
index = obj.index
index
Out[17]: Index(['a', 'b', 'c'], dtype='object')

index[1:]
Out[26]: Index(['b', 'c'], dtype='object')

Index对象是不可修改的(immutable),因此用户不能对其进行修改。这样才能使Index对象在多个数据结构之间安全共享:

index0 = pd.Index(np.arange(3))
obj2 = Series([2,3,4],index=index0)
obj2.index is index0
Out[25]: True

Index甚至可以被继承从而实现特别的轴索引功能

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值