pandas入门

Pandas含有使数据分析工作变得更快更简单的高级数据结构和操作工具。pandas是基于NumPy构建的,让以Numpy为中心的应用变得更加简单。

 

Pandas的两个主要数据结构:Series和DataFrame。

Series

  • Series是一种类似于一维数组的对象,它由数据(各种NumPy数据类型)以及与之相关的数据标签(即索引)组成。
In [2]: from pandas import Series, DataFrame

In [3]: obj = Series([4, 7, -5, 3])

In [4]: obj
Out[4]: 
0    4
1    7
2   -5
3    3
dtype: int64
  • 可以通过Series的values和index属性获取其数组表示形式和索引对象:
  • In [5]: obj.values Out[5]: array([ 4, 7, -5, 3]) In [6]: obj.index Out[6]: RangeIndex(start=0, stop=4, step=1)

 

  • 可以通过索引的方式选取Series中的单个或一组值
  • NumPy数组运算(如根据布尔型数组进行过滤、标量乘法、应用数学函数等)都会保留索引和值之间的链接:
In [7]: obj[obj>2]
Out[7]: 
0    4
1    7
3    3
dtype: int64

In [8]: obj*2
Out[8]: 
0     8
1    14
2   -10
3     6
dtype: int64

 

  • 还可以将Series看成是一个定长的有序字典,因为它是索引值到数据值的一个映射:
0 in obj
Out[9]: True
  • Python字典中的数据也可以直接创建Series:
In [10]: sdata = {'Ohio':35000, 'Texas':71000, 'Oregon':16000, 'Utah':5000}

In [11]: obj3 = Series(sdata)

In [12]: obj3
Out[12]: 
Ohio      35000
Oregon    16000
Texas     71000
Utah       5000
dtype: int64
  • Pandas的isnull和notnull函数可用于检测缺失数据:
In [14]: import pandas as pd
In [16]: pd.isnull(obj3)
Out[16]: 
Ohio      False
Oregon    False
Texas     False
Utah      False
dtype: bool
  • Series对象本身及其索引都有一个name属性
In [17]: obj3.name = 'population'
In [18]: obj3.index.name = 'state'
In [19]: obj3
Out[20]: 
state
Ohio      35000
Oregon    16000
Texas     71000
Utah       5000
Name: population, dtype: int64

 

Series最重要的一个功能:它在算术运算中会自动对齐不同索引的数据。

 

 DataFrame

  • DataFrame是一个表格型数据,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame即有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)。
from pandas import Series, DataFrame
data = {'state':['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year':[2000, 2001, 2002, 2001, 2001],
        'pop':[1.5, 1.7, 3.6, 2.4, 2.9]}

frame = DataFrame(data);
print (frame)

 

  • 结果DataFrame会自动加上索引,且全部列会被有序排列:
   pop   state  year
0  1.5    Ohio  2000
1  1.7    Ohio  2001
2  3.6    Ohio  2002
3  2.4  Nevada  2001
4  2.9  Nevada  2001

 

  • 如果指定了列序列,则DataFrame的列就会按照指定的顺序进行排序:
frame2 = DataFrame(data,columns=['year', 'state', 'pop'])

 

  • 传入的列在数据中找不到,就会产生NA值。
  • 通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series:
print (frame2['state'])
print (frame2.year)

 

  输出:

0      Ohio
1      Ohio
2      Ohio
3    Nevada
4    Nevada
Name: state, dtype: object
0    2000
1    2001
2    2002
3    2001
4    2001
Name: year, dtype: int64
  • 行也可以通过位置或名称的方式进行获取,比如用索引字段 ix
  • 跟Series一样,如果传入的列在数据中找不到,就会产生NA值:
frame3 = DataFrame(data,columns=['year', 'state', 'pop', 'debt'])
print (frame3)

 

  输出:

   year   state  pop debt
0  2000    Ohio  1.5  NaN
1  2001    Ohio  1.7  NaN
2  2002    Ohio  3.6  NaN
3  2001  Nevada  2.4  NaN
4  2001  Nevada  2.9  NaN

  列可以通过赋值的方式修改:

frame3['debt'] = np.arange(5.0)
print (frame3)

  输出:

   year   state  pop  debt
0  2000    Ohio  1.5   0.0
1  2001    Ohio  1.7   1.0
2  2002    Ohio  3.6   2.0
3  2001  Nevada  2.4   3.0
4  2001  Nevada  2.9   4.0
  • 将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度想匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值:
val = Series([-1.2, -1.5, -1.7], index=[ 0, 2, 3])
frame3['debt'] = val
print (frame3)

  输出:

   year   state  pop  debt
0  2000    Ohio  1.5  -1.2
1  2001    Ohio  1.7   NaN
2  2002    Ohio  3.6  -1.5
3  2001  Nevada  2.4  -1.7
4  2001  Nevada  2.9   NaN

 

注意:通过索引方式返回的列只是相应数据的视图,并不是副本

  • 另一种常见的数据形式是嵌套字典(字典的字典):

 

pop = {'Nevada':{2001:2.4, 2002:2.9},
       'Ohio': {2000:2.5, 2001:1.7, 2002:3.6}}

frame4 = DataFrame(pop)
print (frame4)

 

  输出:

      Nevada  Ohio
2000     NaN   2.5
2001     2.4   1.7
2002     2.9   3.6

 

  转置:

frame4.T
  • 由Series组成的字典用法类似
  • 如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来:
frame4 = DataFrame(pop)
frame4.index.name = 'year'
frame4.columns.name = 'state'
print (frame4)

  输出:

state  Nevada  Ohio
year               
2000      NaN   2.5
2001      2.4   1.7
2002      2.9   3.6

 

  • 跟Series一样,values属性也会以二维ndarray的形式返回DataFrame中的数据:
print (frame4.values)
#输出
[[ nan  2.5]
 [ 2.4  1.7]
 [ 2.9  3.6]]

 

基本功能

重新索引

  • 调用该Series的reindex将会根据数据索引进行重排。如果某个索引值当前不存在,就引入缺失值NaN:
obj = Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a' , 'c'])
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
print (obj2)
#输出
a   -5.3
b    7.2
c    3.6
d    4.5
e    NaN
dtype: float64

 

  • 使用 fill_value 可做插值处理
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
print (obj2)
#输出
a   -5.3
b    7.2
c    3.6
d    4.5
e    0.0
dtype: float64
  • method选项
obj3 = Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
print (obj3.reindex(range(6), method='ffill'))
#输出
0      blue
1      blue
2    purple
3    purple
4    yellow
5    yellow
dtype: object
参数 说明
ffill或pad 前向填充值
bfill或backfill 后向填充值

 

 

 

 

  • 对于DataFrame,reindex可以修改(行)索引、列,或两个都修改。
frame = DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio', 'Texas', 'California'])

frame2 = frame.reindex(['a', 'b', 'c', 'd'])

states = ['Texas', 'Utah', 'California']
frame3 = frame.reindex(columns=states)

  利用ix的标签索引功能,重新索引任务可以变的更简洁:

frame.ix[['a', 'b', 'c', 'd'], states]

 

 

丢弃指定轴上的项

  • 丢掉某条轴上的一个或多个项,只要有一个索引数组或列表即可,使用 drop 方法 
data = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two', 'three', 'four'])
print (data.drop(['Colorado', 'Ohio']))
print (data.drop(['two', 'three'], axis=1))

 

 

索引、选取和过滤

  • Series索引的几个例子:
obj = Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
obj['b']
obj[1]
obj[2:4]
obj['b', 'a', 'd']
obj[[1,3]]
obj[obj<2]
obj['b', 'c']

 

  • DataFrame索引:
data = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio', 'Colorado', 'Utah', 

data[['two', 'three']]
#输出
          two  three
Ohio        1      2
Colorado    5      6
Utah        9     10
New York   13     14

data[:2]
#输出
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7

data[data['three']>5]
#输出
          one  two  three  four
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
  • 专门的索引字段ix
类型 说明
obj[val] 选取DataFrame的单个列或一组列
obj.ix[val] 选取DataFrame的单个行或一组行
obj.ix[:,val] 选取单个列或列子集
obj.ix[val1,val2] 同时选取行和列

 

 

 

 

 

 

 

 

算术运算和数据对齐

  • pandas最重要的一个功能是,它可以对不同的索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。
  • 使用df1的 add 方法,传入df2以及一个fill_value参数:
df1 = DataFrame(np.arange(12.).reshape((3,4)), columns= list('abcd'))
df2 = DataFrame(np.arange(20.).reshape((4,5)), columns= list('abcde'))
print(df1+df2)
print(df1.add(df2,fill_value=0))
#输出
      a     b     c     d   e
0   0.0   2.0   4.0   6.0 NaN
1   9.0  11.0  13.0  15.0 NaN
2  18.0  20.0  22.0  24.0 NaN
3   NaN   NaN   NaN   NaN NaN
      a     b     c     d     e
0   0.0   2.0   4.0   6.0   4.0
1   9.0  11.0  13.0  15.0   9.0
2  18.0  20.0  22.0  24.0  14.0
3  15.0  16.0  17.0  18.0  19.0
  • 在对Series或DataFrame重新索引时,也可以指定一个填充值:
df1.reindex(columns=df2.columns, fill_value=0)
#输出
     a    b     c     d  e
0  0.0  1.0   2.0   3.0  0
1  4.0  5.0   6.0   7.0  0
2  8.0  9.0  10.0  11.0  0
  • 默认情况下,DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播
  • 如果某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集。

 

函数应用和映射

  • NumPy的ufuncs(元素级数组方法)也可以用于操作pandas对象:
#示例
np.abs(frame)

 

  • 另一种常见的操作是,将函数应用到各列或行所形成的一维数组上。使用DataFrame的 apply 方法。
frame = DataFrame(np.random.randn(4,3), columns=list('bde'), index=[1,2,3,4])
print (frame)
f = lambda x:x.max() - x.min()
print (frame.apply(f))
print (frame.apply(f, axis=1))
#输出
          b         d         e
1  0.756197  2.094682 -2.139083
2  0.231391 -0.682302  0.908212
3  0.447181 -0.172543  0.221593
4 -0.500720  0.248337 -0.034403
b    1.256918
d    2.776984
e    3.047295
dtype: float64
1    4.233765
2    1.590513
3    0.619723
4    0.749058
dtype: float64

 

  • 元素级的Python函数也是可以用的:
format = lambda x: '%.2f' %x
print (frame.applymap(format))

  之所以叫applymap,是因为Series有一个勇于应用元素级函数的map方法:

print (frame['e'].map(format))
#输出
       b      d      e
1  -0.84   0.10   1.07
2   0.56  -0.49  -1.98
3  -0.60  -1.57  -1.42
4   0.53  -0.85  -0.01
1 1.07 2 -1.98 3 -1.42 4 -0.01 Name: e, dtype: object

 

排序和排名

  • 要对行或列索引进行排序(按字典顺序),可使用 sort_index 方法,它将返回一个已排序的心对象: 
obj = Series(range(4), index=['d', 'a', 'b', 'c'])
print (obj.sort_index())
#输出
a    1
b    2
c    3
d    0
dtype: int64

 

  默认升序,降序如下:

obj.sort_index(axis=1, ascending=False)
  • 对Series进行排序,可使用其 order 方法:

 

  • 在DataFrame上,将一个或多个列的名字传递给 by 选项即可根据一个或多个列中的进行排序:
frame = DataFrame({'b':[4, 7, -3, 2], 'a':[0, 1, 0 , 1]})
print (frame.sort_values(by=['a','b']))
#输出
   a  b
2  0 -3
0  0  4
3  1  2
1  1  7

 

带有重复值的轴索引

  • 许多pandas函数(如reindex)要求标签唯一,但这并不是强制性的。
obj = Series(range(5),index=['a', 'a', 'b', 'b', 'c'])

  索引的 is_unique 属性可以告诉你它的值是否唯一 

obj.index.is_unique
  • 对于带有重复值的索引,如果某个索引对应多个值,则返回一个Series,而对应单个值的,则返回一个标量值。
  • 对DataFrame的行进行索引时也是如此。

 

汇总和计算描述统计

  • pandas对象拥有一组常用的数学和统计方法。它们大部分都属于约简和汇总统计,用于从Series中提取单个值(如sum或mean)或从DataFrame的行或列中提取一个Series。
df = DataFrame([[1.4, np.nan], [7.1, -4.5], [np.nan, np.nan], [0.75, -1.3]], index=['a', 'b', 'c', 'd'], columns=['one', 'two'])
print (df)
print (df.sum())
print (df.sum(axis=1)) #axis 约简的轴。DataFrame的行用0,列用1

#输出
    one  two
a  1.40  NaN
b  7.10 -4.5
c   NaN  NaN
d  0.75 -1.3
one    9.25
two   -5.80
dtype: float64
a    1.40
b    2.60
c     NaN
d   -0.55
dtype: float64

 

  NA值会自动被排除,除非整个切片(这里指的是行或列)都是NA。通过 skipna 选项可以禁用该功能。

  • 有些方法(如 idxminidxmax )返回的是间接统计(比如达到最小值或最大值的索引)

 

相关系数和协方差

  • Series的 corr 方法用于计算两个Series中重叠的、非NA的、按索引对齐的值的相关系数。与此类似,cov 用于计算协方差。
  • DataFrame的 corrcov 方法将以DataFrame的形式返回完整的相关系数或协方差矩阵。

 

唯一值、值计数以及成员资格

  • unique 函数可以得到Series中的唯一值数组:
obj = Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])
uniques = obj.unique()
print (uniques)
#输出
['c' 'a' 'd' 'b']

  返回的唯一值是为排序的,可使用 uniques.sort() 进行排序

  • value_counts 用于计算一个Series中各值出现的频率:
print (obj.value_counts())
#输出
c    3
a    3
b    2
d    1
dtype: int64

  结果是按值频率降序排列的。

pd.value_counts(obj.values, sort=False)

 

  • isin 用于判断矢量化集合的成员资格,可用于选取Series中或DataFrame列中数据的子集:
mask = obj.isin(['b','c'])
print (mask)
#输出
0     True
1    False
2    False
3    False
4    False
5     True
6     True
7     True
8     True
dtype: bool

 

 

处理缺失数据

  • pandas使用浮点值 NaN(Not a Number)表示浮点和非浮点数组中的缺失数据,它只是一个用于被检测出来的标记而已:

 

string_data = Series(['aa', 'bb', np.nan, 'cc'])
print (string_data.isnull())
#输出
0    False
1    False
2     True
3    False
dtype: bool

 

  Python内置的 None 值也会被当作NA处理。

  • NA处理方法
方法 说明
dropna 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阀值调节对缺失值的容忍度
fillna 用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull 返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值/NA,该对象的类型与源类型一样
notnull isnull的否定式

 

 

 

 

 

 

 

 

滤除缺失数据

  • 对于一个Series,dropna 返回一个仅含非空数据和索引值的Series:
data = Series([1, np.nan, 3.5, np.nan, 7])
print (data.dropna())
#输出
0    1.0
2    3.5
4    7.0
dtype: float64
  • 对于DataFrame对象,dropna 默认丢弃任何含有缺失值的

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

data.dropna(how='all')

  以这种方式丢弃列:

data.dropna(axis=1, how='all')

 

 

填充缺失数据

  • 通常一个常数调用 fillna 就会将缺失值替换为那个常数:
df.fillna(0)
  • 若通过一个字典调用 fillna ,就可以实现对不同的 列 填充不同的值:
df.fillna({1:0.5, 3:-1})

 

注:fillna 默认返回新对象,但也可以对现有对象进行修改:

#总是返回被填充对象的引用
_ = df.fillna(o, inplace=True)
  • reindex 有效的那些插值方法也可以用于fillna:
#df.fillna(method='ffill')
df.fillna(method='ffill', limit=2) #(对于前向和后向填充)可以连续填充的最大数量
#输出
          0         1         2
0 -2.512334  0.566809 -0.310823
1  1.480002  0.089615 -0.876138
2  1.446703  0.089615 -0.705835
3 -0.241433  0.089615  0.897966
4  0.028517       NaN  0.897966
5 -0.045509       NaN  0.897966

 

 

层次化索引

  • 层次化索引能使你能在一个轴上拥有多个(两个以上)索引级别:
data = Series(np.random.randn(10),
              index=[['a','a','a','b','b','b','c','c','d','d'],[1,2,3,1,2,3,1,2,1,2]])
print (data)
print (data.index)
#输出
a  1   -0.041274
   2    1.288469
   3   -0.731776
b  1    1.411813
   2   -1.108839
   3   -0.689199
c  1   -0.185918
   2    0.803436
d  1    0.094525
   2    0.692778
dtype: float64

MultiIndex(levels=[[u'a', u'b', u'c', u'd'], [1, 2, 3]],
           labels=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 0, 1]])
  • 对于一个层次化索引的对象选取数据子集操作:
data['b']
data['b':'c']
data.ix[['b', 'd']]

  在内层中选取:

data[:, 2]
#输出
a    0.780424
b    0.034343
c   -1.635875
d   -1.068981
dtype: float64

 

 

重排分级顺序

  • 重新调整某条轴上各级别的顺序,swaplevel 接收两个级别编号或名称,并返回互换了级别的新对象(但数据不会发生变化):
frame = DataFrame(np.arange(12).reshape(4,3),
                  index=[['a','a','b','b'], [1,2,1,2]],
                  columns=[['Ohio', 'Ohio', 'Colorado'],
                           ['Green', 'Red', 'Green']])
frame.index.names = ['key1', 'key2']
frame.columns.names = ['state', 'color']
#输出
state Ohio Colorado
color Green Red Green
key1 key2 
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11


frame.swaplevel('key1', 'key2')

 

  • sortlevel根据单个级别中的值对数据进行排序(稳定):
frame.sort_index(level=1)
#输出
state      Ohio     Colorado
color     Green Red    Green
key1 key2                   
a    1        0   1        2
b    1        6   7        8
a    2        3   4        5
b    2        9  10       11

 

  •  交换级别:
frame.swaplevel(0,1).sort_index(level=0)
#输出
state      Ohio     Colorado
color     Green Red    Green
key2 key1                   
1    a        0   1        2
     b        6   7        8
2    a        3   4        5
     b        9  10       11

 

 

根据级别汇总统计

  • 许多对DataFrame和Series的描述和汇总统计都有一个level选项,它用于指定在某条轴上求和的级别。
#示例
frame.sum(level='key2')
#输出
state  Ohio     Colorado
color Green Red    Green
key2                    
1         6   8       10
2        12  14       16
frame.sum(level='color', axis=1)
#输出
color      Green  Red
key1 key2            
a    1         2    1
     2         8    4
b    1        14    7
     2        20   10

 

 

使用DataFrame的列

  • 人们经常想要将DataFrame的一个或多个列当作索引来用,或者可能希望将行索引变成DataFrame的列:
frame = DataFrame({'a':range(7), 'b':range(7,0,-1), 'c':['one','one','one','two','two','two','two'],
                   'd':[0,1,2,0,1,2,3]})
print frame
#输出
   a  b    c  d
0  0  7  one  0
1  1  6  one  1
2  2  5  one  2
3  3  4  two  0
4  4  3  two  1
5  5  2  two  2
6  6  1  two  3
  • DataFrame的 set_index 函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame:
frame2 = frame.set_index(['c','d'])
#输出
       a  b
c   d      
one 0  0  7
    1  1  6
    2  2  5
two 0  3  4
    1  4  3
    2  5  2
    3  6  1

 

  • reset_index 的功能跟 set_index 刚好相反,层次化索引的级别会被转移到列里面:
frame2.reset_index()

 

posted @ 2017-06-09 17:05  dear_diary  阅读(543)  评论(0编辑  收藏  举报