pandas简介

pandas是基于NumPy构建的,让以NumPy为中心的应用变得更加简单。

引入约定

from pandas import Series,DataFrame
import pandas as pd

pandas的数据结构

Series和DataFrame

Series

Series是一种类似一维数组的对象,由一组数据和相关的索引组成。

>>> obj = Series([4,7,-5,3])
>>> obj
0    4
1    7
2   -5
3    3
dtype: int64

它的索引写在左边一列。

可以通过values和index属性获取数组表示形式和索引对象。

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

它的索引可以通过如下的方式自定义:

>>> obj2 = Series([4,7,-5,3],index=['d','b','a','c'])
>>> obj2
d    4
b    7
a   -5
c    3
dtype: int64
>>> obj2.index
Index([u'd', u'b', u'a', u'c'], dtype='object')

访问和设置值:

>>> obj2['a']
-5
>>> obj2['a'] = 5
>>> obj2
d    4
b    7
a    5
c    3
dtype: int64
>>> obj2['a']
5
>>> obj2[obj2>4]
b    7
a    5
dtype: int64
>>> obj2 * 2
d     8
b    14
a    10
c     6
dtype: int64
>>> np.exp(obj2)
d      54.598150
b    1096.633158
a     148.413159
c      20.085537
dtype: float64

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

>>> obj.index = ['bob','steve','jeff','ryan']
>>> obj
bob      1
steve    2
jeff     3
ryan     4

DataFrame

是一个表格型的数据结构。既有行索引,也有列索引。

构建DataFrame:
下面是通过由等长列表构成的字典构造:

>>> data = {'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],'year':[2000,2001,2002,2001,2002],'pop':[1.1,2.2,3.3,4.4,2.9]}
>>> frame = DataFrame(data)
>>> frame
   pop   state  year
0  1.1    Ohio  2000
1  2.2    Ohio  2001
2  3.3    Ohio  2002
3  4.4  Nevada  2001
4  2.9  Nevada  2002

还可以指定列的序列。

>>> DataFrame(data,columns=['year','state','pop'])
   year   state  pop
0  2000    Ohio  1.1
1  2001    Ohio  2.2
2  2002    Ohio  3.3
3  2001  Nevada  4.4
4  2002  Nevada  2.9

可以通过以下方式,将DataFrame的列以Series的形式获取:

>>> frame['state']
0      Ohio
1      Ohio
2      Ohio
3    Nevada
4    Nevada
Name: state, dtype: object
>>> frame.year
0    2000
1    2001
2    2002
3    2001
4    2002
Name: year, dtype: int64

行也可以通过为止或名称的方式进行获取:

>>> frame.ix[2]
pop       3.3
state    Ohio
year     2002
Name: 2, dtype: object

可通过赋值的方式修改或添加列:

>>> frame['new_line'] = 5.5
>>> frame
   pop   state  year  new_line
0  1.1    Ohio  2000       5.5
1  2.2    Ohio  2001       5.5
2  3.3    Ohio  2002       5.5
3  4.4  Nevada  2001       5.5
4  2.9  Nevada  2002       5.5

>>> frame['new_line'] = np.arange(5.)
>>> frame
   pop   state  year  new_line
0  1.1    Ohio  2000       0.0
1  2.2    Ohio  2001       1.0
2  3.3    Ohio  2002       2.0
3  4.4  Nevada  2001       3.0
4  2.9  Nevada  2002       4.0

del用于删除列:

>>> del frame['new_line']
>>> frame
   pop   state  year
0  1.1    Ohio  2000
1  2.2    Ohio  2001
2  3.3    Ohio  2002
3  4.4  Nevada  2001
4  2.9  Nevada  2002

通过索引方式返回的列是相应数据的视图,对返回的Series所做的任何就地修改全都会反映到源DataFrame上。

还有一种常见的数据形式是嵌套字典,它会解释为:外层字典的键作为列(Nevada、Ohio);内层键则作为行索引:

>>> pop = {'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,2002:3.6}}
>>> frame = DataFrame(pop)
>>> frame
      Nevada  Ohio
2000     NaN   1.5
2001     2.4   1.7
2002     2.9   3.6

如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来:

>>> frame.index.name = 'year'
>>> frame.columns.name='state'
>>> frame
state  Nevada  Ohio
year               
2000      NaN   1.5
2001      2.4   1.7
2002      2.9   3.6

values属性会以二维ndarray的形式返回DataFrame中的数据:

>>> frame.values
array([[ nan,  1.5],
       [ 2.4,  1.7],
       [ 2.9,  3.6]])

基本功能

重新索引

创建一个适应新索引的新对象

>>> obj = Series([4.5,7.2,-5.3,3.6],index = ['d','b','a','c'])
>>> obj
d    4.5
b    7.2
a   -5.3
c    3.6
dtype: float64
>>> obj2 = obj.reindex(['a','b','c','d','e'])
>>> obj2
a   -5.3
b    7.2
c    3.6
d    4.5
e    NaN
dtype: float64

>>> obj.reindex(['a','b','c','d','e'],fill_value=0)
a   -5.3
b    7.2
c    3.6
d    4.5
e    0.0
dtype: float64

method选项中的ffill参数可以向前搬运值

>>> obj3 = Series(['blue','purple','yellow'],index = [0,2,4])
>>> obj3
0      blue
2    purple
4    yellow
dtype: object
>>> obj3.reindex(range(6),method='ffill')
0      blue
1      blue
2    purple
3    purple
4    yellow
5    yellow
dtype: object

0,2,4分别对应blue,purple,yellow。1,3,5取的是前一个索引的值。

参数 说明
ffill或pad 向前搬运值
bfill或backfill 向后搬运值

索引、选取和过滤

>>> obj = Series(np.arange(4.),index=['a','b','c','d'])
>>> obj['b']
1.0
>>> obj
a    0.0
b    1.0
c    2.0
d    3.0
dtype: float64
>>> obj[1]
1.0
>>> obj[obj<2]
a    0.0
b    1.0
dtype: float64
>>> obj['b':'c'] #这与Python切片运算不同,其末端是包含的。即封闭区间
b    1.0
c    2.0
dtype: float64

对DataFrame进行索引其实就是获取一个或多个

>>> data = DataFrame(np.arange(16).reshape((4,4)),index=['Shenzhen','Shanghai','Changsha','Beijing'],columns=['one','two','three','four'])
>>> data
          one  two  three  four
Shenzhen    0    1      2     3
Shanghai    4    5      6     7
Changsha    8    9     10    11
Beijing    12   13     14    15
>>> data['two']
Shenzhen     1
Shanghai     5
Changsha     9
Beijing     13
Name: two, dtype: int32
>>> data[['three','one']]
          three  one
Shenzhen      2    0
Shanghai      6    4
Changsha     10    8
Beijing      14   12

这种索引方式有几个特殊情况,首先通过切片或布尔型数组选取

>>> data[:2]
          one  two  three  four
Shenzhen    0    1      2     3
Shanghai    4    5      6     7
>>> data[data['three']>5] #就是2,3,4行;three列的第一行是2,不满足条件
          one  two  three  four
Shanghai    4    5      6     7
Changsha    8    9     10    11
Beijing    12   13     14    15

另一种用法是通过布尔型DataFrame(下面这个由标量比较运算得出)进行索引:

>>> data<5
            one    two  three   four
Shenzhen   True   True   True   True
Shanghai   True  False  False  False
Changsha  False  False  False  False
Beijing   False  False  False  False
>>> data[data<5] = 0
>>> data
          one  two  three  four
Shenzhen    0    0      0     0
Shanghai    0    5      6     7
Changsha    8    9     10    11
Beijing    12   13     14    15

索引字段ix,通过它可以用NumPy式的标记法以及轴标签从DataFrame中选取行和列的子集。这是一种重新索引的简单手段:

>>> data.ix['Shanghai',['two','three']] #选取行'Shanghai',列'two','three'
two      5
three    6
Name: Shanghai, dtype: int32
>>> data.ix[2] #选取第3(索引从0开始)行,这里是以列的形式展示
one       8
two       9
three    10
four     11
Name: Changsha, dtype: int32
>>> data.ix[:'Changsha','two'] #选取前3行,第2列
Shenzhen    0
Shanghai    5
Changsha    9
Name: two, dtype: int32
>>> data.ix[data.three>5,:3]#选取后三行,前三列
          one  two  three
Shanghai    0    5      6
Changsha    8    9     10
Beijing    12   13     14

DataFrame的索引选项


DataFrame和Series之间的运算

计算一个二维数组与其某行之间的差:

>>> arr = np.arange(12.).reshape((3,4))
>>> arr
array([[  0.,   1.,   2.,   3.],
       [  4.,   5.,   6.,   7.],
       [  8.,   9.,  10.,  11.]])
>>> arr[0]
array([ 0.,  1.,  2.,  3.])
>>> arr - arr[0]
array([[ 0.,  0.,  0.,  0.],
       [ 4.,  4.,  4.,  4.],
       [ 8.,  8.,  8.,  8.]])

这叫做广播。DataFrame与Series之间的运算差不多也是如此:

>>> df1 = DataFrame(np.arange(9.).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])
>>> df2 = DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
>>> df1
            b    c    d
Ohio      0.0  1.0  2.0
Texas     3.0  4.0  5.0
Colorado  6.0  7.0  8.0
>>> df2
          b     d     e
Utah    0.0   1.0   2.0
Ohio    3.0   4.0   5.0
Texas   6.0   7.0   8.0
Oregon  9.0  10.0  11.0
>>> df1 + df2 #相加后的DataFrame索引和列为原来的两个DataFrame的并集
            b   c     d   e
Colorado  NaN NaN   NaN NaN
Ohio      3.0 NaN   6.0 NaN
Oregon    NaN NaN   NaN NaN
Texas     9.0 NaN  12.0 NaN
Utah      NaN NaN   NaN NaN

函数应用和映射

NumPy的元素级别方法也可用于操作pandas对象:

>>> frame = DataFrame(np.random.randn(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
>>> frame
               b         d         e
Utah   -0.754242  1.374050 -2.396724
Ohio   -0.919466  1.220883 -0.933032
Texas   1.874174 -2.341060  1.043491
Oregon  0.265324 -0.557416 -0.347104
>>> np.abs(frame)
               b         d         e
Utah    0.754242  1.374050  2.396724
Ohio    0.919466  1.220883  0.933032
Texas   1.874174  2.341060  1.043491
Oregon  0.265324  0.557416  0.347104

还可以将函数应用到由各列或行所形成的一维数组上。DataFrame的apply方法即可实现此功能:

>>> f = lambda x: x.max() - x.min()
>>> frame.apply(f)
b    2.793640
d    3.715110
e    3.440215
dtype: float64

轴是为超过一维的数组定义的属性,二维数据拥有两个轴:第0轴沿着行的垂直往下,第1轴沿着列的方向水平延伸。
Pandas保持了Numpy对关键字axis的用法,用法在Numpy库的词汇表当中有过解释:
如果简单点来说,就是0轴匹配的是index, 涉及上下运算;1轴匹配的是columns, 涉及左右运算。

>>> frame.apply(f,axis=1)
Utah      3.770774
Ohio      2.153916
Texas     4.215234
Oregon    0.822741
dtype: float64

>>> frame.apply(f,axis=0)
b    2.793640
d    3.715110
e    3.440215

元素级的函数也是可以用的,如果想得到frame中各个浮点值的格式化字符串,使用applymap即可:

>>> format = lambda x: '%.2f' % x
>>> frame.applymap(format)
            b      d      e
Utah    -0.75   1.37  -2.40
Ohio    -0.92   1.22  -0.93
Texas    1.87  -2.34   1.04
Oregon   0.27  -0.56  -0.35

排序和排名

根据索引排序:

>>> obj = Series(range(4),index=list('dabc'))
>>> obj.sort_index()
a    1
b    2
c    3
d    0

对于DataFrame,则可以根据任意一个轴上的索引来进行排序:

>>> frame = DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=list('dabc'))
>>> frame
       d  a  b  c
three  0  1  2  3
one    4  5  6  7
>>> frame.sort_index()
       d  a  b  c
one    4  5  6  7
three  0  1  2  3
>>> frame.sort_index(axis=1)
       a  b  c  d
three  1  2  3  0
one    5  6  7  4

如果要按值进行排序,对于Series来说,使用其sort_values方法:

>>> obj.sort_values()
2   -3
3    2
0    4
1    7

对于DataFrame,可根据一个或多个列中的值进行排序,将这些列的名称传递给by选项即可:

>>> frame = DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]})
>>> frame
   a  b
0  0  4
1  1  7
2  0 -3
3  1  2
>>> frame.sort_index(by='b')
<string>:1: FutureWarning: by argument to sort_index is deprecated, please use .sort_values(by=...)
   a  b
2  0 -3
3  1  2
0  0  4
1  1  7
>>> frame.sort_values(by='b') #那么就用sort_values
   a  b
2  0 -3
3  1  2
0  0  4
1  1  7

处理缺失数据

pandas使用NaN表示负电和非浮点数组中的缺失数据。

NA处理方法

方法 说明
dropna 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈值调节对缺失值的容忍度
fillna 用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull 返回一个含有布尔值的对象
notnull isnull的否定式

滤除缺失数据

对于一个Series,dropna返回一个仅含非空数据和索引值的Series:

>>> from numpy import nan as NA
>>> data = Series([1,NA,3.5,NA,7])
>>> data.dropna()
0    1.0
2    3.5
4    7.0
dtype: float64

对于DataFrame对象,你可能希望丢弃全NA或含有NA的行或列。dropna默认丢弃任何含有缺失值的行:

>>> data = DataFrame([[1.,6.5,3.],[1.,NA,NA],[NA,NA,NA],[NA,6.5,3.]])
>>> data
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0
>>> data.dropna()
     0    1    2
0  1.0  6.5  3.0

传入how=’all’将只会丢弃全为NA的那些行:

>>> data.dropna(how='all')
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
3  NaN  6.5  3.0

如果同时传入axis=1,就会丢弃列:

>>> data[4] = NA
>>> data
     0    1    2   4
0  1.0  6.5  3.0 NaN
1  1.0  NaN  NaN NaN
2  NaN  NaN  NaN NaN
3  NaN  6.5  3.0 NaN
>>> data.dropna(axis=1,how='all')
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0

填充缺失数据

>>> df
          0         1         2
0 -0.526012       NaN       NaN
1 -0.046144       NaN       NaN
2 -0.606856       NaN       NaN
3 -0.793046       NaN -0.367388
4 -0.494585       NaN -1.773408
5 -0.011493 -0.542106 -0.714098
6 -1.218056  0.023548 -1.239914
>>> df.fillna(0)
          0         1         2
0 -0.526012  0.000000  0.000000
1 -0.046144  0.000000  0.000000
2 -0.606856  0.000000  0.000000
3 -0.793046  0.000000 -0.367388
4 -0.494585  0.000000 -1.773408
5 -0.011493 -0.542106 -0.714098
6 -1.218056  0.023548 -1.239914

如果通过一个字典调用fillna,就可以实现对不同的列填充不同的值:

>>> df.fillna({1:0.5,3:-1}) #这里没有索引为3的列
          0         1         2
0 -0.526012  0.500000       NaN
1 -0.046144  0.500000       NaN
2 -0.606856  0.500000       NaN
3 -0.793046  0.500000 -0.367388
4 -0.494585  0.500000 -1.773408
5 -0.011493 -0.542106 -0.714098
6 -1.218056  0.023548 -1.239914

猜你喜欢

转载自blog.csdn.net/yjw123456/article/details/78968132