python基础篇之Pandas(一)

基本数据结构介绍

1、Pandas介绍

  Pandas是Python在数据处理方面功能最为强大的扩展模块。在Python中,Pandas包含了高级的数据结构Series和DataFrame,使得在Python中处理数据变得非常方便、快速和简单。

  Pandas不同的版本之间存在一些不兼容性,为此,我们需要清楚使用的是哪一个版本的Pandas。查看Pandas版本:

1 import pandas as pd
2 pd.__version__
'0.20.3'

    Pandas主要的两个数据结构是Series和DataFrame,随后将介绍如何由其他类型的数据结构得到这两种数据结构,或者自行创建这两种数据结构,先导入它们以及相关模块:


1 import numpy as np
2 from pandas import Series, DataFrame

2、Pandas数据结构:Series

  从一般意义上来讲,Series可以简单地被认为是一维的数组。Series和一维数组最主要的区别在于Series类型具有索引(index),可以和另一个编程中常见的数据结构哈希(Hash)联系起来。

  2.1、创建Series  

  创建一个Series的基本格式是:s = Series(data, index=index, name=name),以下给出几个创建Series的实例。首先我们从数组创建Series:

# 从数组创建Series
1
a = np.random.rand(5) 2 print ('a is an array :') 3 print (a) 4 a = Series(a) 5 print ('a is a series :') 6 print (a)
a is an array :
[ 0.38687385  0.35870029  0.54675218  0.47525425  0.4584288 ]
a is a series :
0    0.386874
1    0.358700
2    0.546752
3    0.475254
4    0.458429
dtype: float64

  可以在创建Series时添加index,并可使用Series.index查看具体的index。需要注意的是,当从数组创建Series时,若指定index,那么index长度要和data的长度一致:

1 s = Series(np.random.rand(5),index = ['a','b','c','d','e'])
2 print (s)
3 s.index
a    0.490576
b    0.137942
c    0.111968
d    0.678880
e    0.703218
dtype: float64
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

  创建Series的另一个可选项是name,指定Series的名称,可用Series.name访问。在随后的DataFrame中,每一列的列名在该列被单独取出来时就成了Series的名称:

1 s = Series(np.random.rand(5),index = ['a','b','c','d','e'],name = 's_series')
2 print (s)
3 print (s.name)
a    0.569505
b    0.280611
c    0.485361
d    0.100137
e    0.765883
Name: s_series, dtype: float64
s_series

  Series还可以从字典(dict)创建:

# 从字典创建Series
1
d = {'a': 0., 'b': 1, 'c': 2} 2 print ("d is a dict:") 3 print (d) 4 e = Series(d) 5 print ("s is a Series:") 6 print (e)
d is a dict:
{'a': 0.0, 'b': 1, 'c': 2}
s is a Series:
a    0.0
b    1.0
c    2.0
dtype: float64

  来看看使用字典创建Series时指定index的情形(index长度不必和字典相同):

Series(d, index=['b', 'c', 'd', 'a'])
b    1.0
c    2.0
d    NaN
a    0.0
dtype: float64

  可以看到:一是字典创建的Series,数据将按index的顺序重新排列;二是index长度可以和字典长度不一致,如果多了的话,pandas将自动为多余的index分配NaN(not a number,pandas中数据缺失的标准记号),当然index少的话就截取部分的字典内容。

  如果数据就是一个单一的变量,如数字4,那么Series将重复这个变量:

Series(4., index=['a', 'b', 'c', 'd', 'e'])
a    4.0
b    4.0
c    4.0
d    4.0
e    4.0
dtype: float64

  2.2 Series数据的访问

  访问Series数据可以和数组一样使用下标,也可以像字典一样使用索引,还可以使用一些条件过滤:

1 s = Series(np.random.randn(10),index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
2 print (s)
3 print (s[0])
a   -1.499113
b   -0.476451
c    0.103055
d    0.302335
e   -1.542407
f   -1.290799
g   -0.388913
h   -0.025543
i    0.795806
j    0.018722
dtype: float64
-1.49911349974

s[:2]
a   -1.499113
b   -0.476451
dtype: float64

s[[2,0,4]]
c    0.103055
a   -1.499113
e   -1.542407
dtype: float64

s[['e', 'i']]
e   -1.542407
i    0.795806
dtype: float64

s[s > 0.5]
i    0.795806
dtype: float64

'e' in s
True

3、Pandas数据结构:DataFrame

  DataFrame是将数个Series按列合并而成的二维数据结构,每一列单独取出来是一个Series,这和SQL数据库中取出的数据是很类似的。所以,按列对一个DataFrame进行处理更为方便,用户在编程时注意培养按列构建数据的思维。DataFrame的优势在于可以方便地处理不同类型的列,因此,就不要考虑如何对一个全是浮点数的DataFrame求逆之类的问题了,处理这种问题还是把数据存成NumPy的matrix类型比较便利一些。

  3.1 创建DataFrame

  首先来看如何从字典创建DataFrame。DataFrame是一个二维的数据结构,是多个Series的集合体。我们先创建一个值是Series的字典,并转换为DataFrame:

1 d = {'one':Series((1,2,3),index = ['a','b','c']),'two':Series((5,6,7,8),index = ['a','b','c','d'])}
2 df = DataFrame(d)
3 print (df)
   one  two
a  1.0    5
b  2.0    6
c  3.0    7
d  NaN    8

  可以指定所需的行和列,若字典中不含有对应的元素,则置为NaN;可以使用dataframe.index和dataframe.columns来查看DataFrame的行和列,dataframe.values则以数组的形式返回DataFrame的元素:

1 df = DataFrame(d,index = ['d','a','r'],columns = ('two','three'))
2 print (df)
3 print ("-----------------")
4 print (df.index)
5 print ("-----------------")
6 print (df.columns)
7 print ("-----------------")
8 print (df.values)
   two three
d  8.0   NaN
a  5.0   NaN
r  NaN   NaN
-----------------
Index(['d', 'a', 'r'], dtype='object')
-----------------
Index(['two', 'three'], dtype='object')
-----------------
[[8.0 nan]
 [5.0 nan]
 [nan nan]]

  在实际处理数据时,有时需要创建一个空的DataFrame,可以这么做:

1 df = DataFrame()
2 print (df)
Empty DataFrame
Columns: []
Index: []

  另一种创建DataFrame的方法十分有用,那就是使用concat函数基于Serie或者DataFrame创建一个DataFrame:

1 a = Series(range(5))
2 b = Series(np.linspace(4,20,5))
3 df = pd.concat([a,b],axis = 1)
4 print (df)
   0     1
0  0   4.0
1  1   8.0
2  2  12.0
3  3  16.0
4  4  20.0

  其中的axis=1表示按列进行合并,axis=0表示按行合并,并且Series都处理成一列,所以这里如果选axis=0的话,将得到一个10×1的DataFrame。下面这个例子展示了如何按行合并DataFrame成一个大的DataFrame:

1 a = DataFrame()
2 index = ['one','two','three','four','five']
3 for i in range(5):
4     df = DataFrame([np.linspace(i,5*i,5)],index = [index[i]],columns=['a','b','c','d','e'])
5     a = pd.concat([a,df],axis = 0)
6 print (a)
         a    b     c     d     e
one    0.0  0.0   0.0   0.0   0.0
two    1.0  2.0   3.0   4.0   5.0
three  2.0  4.0   6.0   8.0  10.0
four   3.0  6.0   9.0  12.0  15.0
five   4.0  8.0  12.0  16.0  20.0

  3.2 DataFrame数据的访问

  首先,强调一下DataFrame是以列作为操作基础的,全部操作都想象成先从DataFrame里取一列,再从这个Series取元素即可。可以用dataframe.column_name选取列,也可以使用dataframe[ ]操作选取列,我们可以马上发现前一种方法只能选取一列,而后一种方法可以选择多列。若DataFrame没有列名,[]可以使用非负整数,也就是“下标”选取列;若有列名,则必须使用列名选取,另外datafrae.column_name在没有列名的时候是无效的:

 1 print (a)
 2 print ()
 3 print (type(a))
 4 print ()
 5 print (a['e'])
 6 print ()
 7 print (a.e)
 8 print ()
 9 print (a[['c','a']])
10 print ()
11 print (a['b']['three'])
        a    b     c     d     e
one    0.0  0.0   0.0   0.0   0.0
two    1.0  2.0   3.0   4.0   5.0
three  2.0  4.0   6.0   8.0  10.0
four   3.0  6.0   9.0  12.0  15.0
five   4.0  8.0  12.0  16.0  20.0

<class 'pandas.core.frame.DataFrame'>

one       0.0
two       5.0
three    10.0
four     15.0
five     20.0
Name: e, dtype: float64

one       0.0
two       5.0
three    10.0
four     15.0
five     20.0
Name: e, dtype: float64

          c    a
one     0.0  0.0
two     3.0  1.0
three   6.0  2.0
four    9.0  3.0
five   12.0  4.0

4.0

  以上代码使用了dataframe.columns为DataFrame赋列名,并且我们看到单独取一列出来,其数据结构显示的是Series,取两列及两列以上的结果仍然是DataFrame。访问特定的元素可以如Series一样使用下标或者是索引:

1 print (a['b'][2])
2 print (a['b']['four'])
4.0
6.0

  若需要选取行,可以使用dataframe.iloc按下标选取,或者使用dataframe.loc按索引选取:

1 print (a.iloc[1])
2 print (a.loc['four'])
a    1.0
b    2.0
c    3.0
d    4.0
e    5.0
Name: two, dtype: float64
a     3.0
b     6.0
c     9.0
d    12.0
e    15.0
Name: four, dtype: float64

  选取行还可以使用切片的方式或者是布尔类型的向量:

1 print ("Selecting by slices:")
2 print (a[1:3])
3 bool_vec = [True, False, True, True, False]
4 print ("Selecting by boolean vector:")
5 print (a[bool_vec])
Selecting by slices:
         a    b    c    d     e
two    1.0  2.0  3.0  4.0   5.0
three  2.0  4.0  6.0  8.0  10.0
Selecting by boolean vector:
         a    b    c     d     e
one    0.0  0.0  0.0   0.0   0.0
three  2.0  4.0  6.0   8.0  10.0
four   3.0  6.0  9.0  12.0  15.0

  行列组合起来选取数据:

1 print (a[['a','e']].iloc[[1,2]])
2 print (a.iloc[[1,2]][['a','e']])
3 print (a[['a','e']].loc[['two','three']])
4 print (a.loc[['two','three']][['a','e']])
         a     e
two    1.0   5.0
three  2.0  10.0
         a     e
two    1.0   5.0
three  2.0  10.0
         a     e
two    1.0   5.0
three  2.0  10.0
         a     e
two    1.0   5.0
three  2.0  10.0

  如果不是需要访问特定行列,而只是某个特殊位置的元素的话,dataframe.at和dataframe.iat是最快的方式,它们分别用于使用索引和下标进行访问:

1 print (a.iat[1,1])
2 print (a.at['two','b'])
2.0
2.0

  dataframe.ix可以混合使用索引和下标进行访问,唯一需要注意的地方是行列内部需要一致,不可以同时使用索引和标签访问行或者列,不然的话,将会得到意外的结果:

1 print (a.ix[[1,2],['a','c']])
2 k = a.ix[[1,2],['a',6]]
3 k[6] = 0
4 print (k)
         a    c
two    1.0  3.0
three  2.0  6.0
         a  6
two    1.0  0
three  2.0  0

 PS:使用dataframe.ix是会出现警告提示,即dataframe.ix的用法是不被赞成使用的。

 

 

posted @ 2018-02-26 17:13  Calex  阅读(481)  评论(0编辑  收藏  举报