机器学习系列二:Pandas

一、pandas概述

pandas :pannel data analysis(面板数据分析)。pandas是基于numpy构建的,pandas是基于NumPy数组构建的,特别是基于数组的函数和不使用for循环的数据处理。为时间序列分析提供了很好的支持。pandas中有两个主要的数据结构,一个是Series,另一个是DataFrame。

import pandas as pd
from pandas import Series, DataFrame

pandas的数据结构介绍

二、数据结构 Series

Series 类似于一维数组与字典(map)数据结构的结合。它由一组数据和一组与数据相对应的数据标签(索引index)组成。这组数据和索引标签的基础都是一个一维ndarray数组。可将index索引理解为行索引。 Series的表现形式为:索引在左,数据在右。

• 获取数据和索引:ser_obj.index, ser_obj.values

• 预览数据:ser_obj.head(n), ser_obj.tail(n)
 

import pandas as pd
from pandas import Series,DataFrame

print '用一维数组生成Series'
x = Series([1,2,3,4]) 
print x
'''
0    1
1    2
2    3
3    4
'''
print x.values # [1 2 3 4]
# 默认标签为0到3的序号
print x.index # RangeIndex(start=0, stop=4, step=1)

print '指定Series的index' # 可将index理解为行索引
x = Series([1, 2, 3, 4], index = ['a', 'b', 'd', 'c'])
print x
'''
a    1
b    2
d    3
c    4
'''
print x.index # Index([u'a', u'b', u'd', u'c'], dtype='object')
print x['a'] # 通过行索引来取得元素值:1
x['d'] = 6 # 通过行索引来赋值
print x[['c', 'a', 'd']] # 类似于numpy的花式索引
'''
c    4
a    1
d    6
'''

print x[x > 2]  # 类似于numpy的布尔索引
'''
d    6
c    4
'''
print 'b' in x # 类似于字典的使用:是否存在该索引:True
print 'e' in x # False
print x*2 #使用NumPy函数或类似NumPy的运算
'''
a    1
b    4
d    6
c    8
'''
print np.exp(x)
'''
a 2.718
b 7.389
c 20.085
d 54.598
'''

print '使用字典来生成Series'
data = {'a':1, 'b':2, 'd':3, 'c':4}
x = Series(data)
print x
'''
a    1
b    2
c    4
d    3
'''
print '使用字典生成Series,并指定额外的index,不匹配的索引部分数据为NaN。'
exindex = ['a', 'b', 'c', 'e']
y = Series(data, index = exindex) # 类似替换索引
print y
'''
a    1.0
b    2.0
c    4.0
e    NaN
'''
print 'Series相加,相同行索引相加,不同行索引则数值为NaN'
print x+y
'''
a    2.0
b    4.0
c    8.0
d    NaN
e    NaN
'''
print '指定Series/索引的名字'
y.name = 'weight of letters'
y.index.name = 'letter'
print y
'''
letter
a    1.0
b    2.0
c    4.0
e    NaN
Name: weight of letters, dtype: float64
'''
print '替换index'
y.index = ['a', 'b', 'c', 'f']
print y # 不匹配的索引部分数据为NaN
'''
a    1.0
b    2.0
c    4.0
f    NaN
Name: weight of letters, dtype: float64
'''

三、数据结构 DataFrame

DataFrame是一个类似表格的数据结构,索引包括列索引和行索引,包含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame的每一行和每一列都是一个Series,这个Series的name属性为当前的行索引名/列索引名。

通过列索引获取列数据(Series类型 ):df_obj[col_idx] 或 df_obj.col_idx

.ix,标签与位置混合索引

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)
print frame
'''
   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  2002
5  3.2  Nevada  2003
'''
print frame.head()#head方法会选取前五行
'''
   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  2002
'''

#如果指定了列序列,则DataFrame的列就会按照指定顺序进行排列:
frame = pd.DataFrame(data, columns=['year', 'state', 'pop'])
print frame
'''
   year   state  pop
0  2000    Ohio  1.5
1  2001    Ohio  1.7
2  2002    Ohio  3.6
3  2001  Nevada  2.4
4  2002  Nevada  2.9
5  2003  Nevada  3.2
'''

#如果传入的列在数据中找不到,就会在结果中产生缺失值:
frame2 = frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
index=['one', 'two', 'three', 'four','five', 'six'])
print frame2
'''
       year   state  pop debt
one    2000    Ohio  1.5  NaN
two    2001    Ohio  1.7  NaN
three  2002    Ohio  3.6  NaN
four   2001  Nevada  2.4  NaN
five   2002  Nevada  2.9  NaN
six    2003  Nevada  3.2  NaN
'''
print frame2.columns #Index(['year', 'state', 'pop', 'debt'], dtype='object')

#通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series
print  frame2['state']
'''
one        Ohio
two        Ohio
three      Ohio
four     Nevada
five     Nevada
six      Nevada
Name: state, dtype: object
'''
print frame2.year
'''
one      2000
two      2001
three    2002
four     2001
five     2002
six      2003
Name: year, dtype: int64
'''
#行也可以通过位置或名称的方式进行获取,比如用loc属性
print  frame2.loc['three']
'''
year     2002
state    Ohio
pop       3.6
debt      NaN
Name: three, dtype: object
'''
#列可以通过赋值的方式进行修改。
frame2['debt'] = 16.5
print frame2
'''
       year   state  pop  debt
one    2000    Ohio  1.5  16.5
two    2001    Ohio  1.7  16.5
three  2002    Ohio  3.6  16.5
four   2001  Nevada  2.4  16.5
five   2002  Nevada  2.9  16.5
six    2003  Nevada  3.2  16.5
'''
frame2['debt'] = np.arange(6.)
print frame2
'''
       year   state  pop  debt
one    2000    Ohio  1.5   0.0
two    2001    Ohio  1.7   1.0
three  2002    Ohio  3.6   2.0
four   2001  Nevada  2.4   3.0
five   2002  Nevada  2.9   4.0
six    2003  Nevada  3.2   5.0
'''
#将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确 
#匹配DataFrame的索引,所有的空位都将被填上缺失值
val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
frame2['debt'] = val
print frame2
'''
       year   state  pop  debt
one    2000    Ohio  1.5   NaN
two    2001    Ohio  1.7  -1.2
three  2002    Ohio  3.6   NaN
four   2001  Nevada  2.4  -1.5
five   2002  Nevada  2.9  -1.7
six    2003  Nevada  3.2   NaN
'''
frame2['eastern'] = frame2.state == 'Ohio'
print frame2
'''
       year   state  pop  debt  eastern
one    2000    Ohio  1.5   NaN     True
two    2001    Ohio  1.7  -1.2     True
three  2002    Ohio  3.6   NaN     True
four   2001  Nevada  2.4  -1.5    False
five   2002  Nevada  2.9  -1.7    False
six    2003  Nevada  3.2   NaN    False
'''
del frame2['eastern']
print frame2.colums #Index(['year', 'state', 'pop', 'debt'], dtype='object')

#另一种常见的数据形式是嵌套字典 如果嵌套字典传给DataFrame,pandas就会被解释为:
#外层字典的键作为列,内层键则作为行索引。
pop = {'Nevada': {2001: 2.4, 2002: 2.9},'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
frame3 = pd.DataFrame(pop)
print frame3
'''
      Nevada  Ohio
2000     NaN   1.5
2001     2.4   1.7
2002     2.9   3.6
'''
#跟Series一样,values属性也会以二维ndarray的形式返回DataFrame中的数据
print frame3.values
'''
array([[ nan,  1.5],
       [ 2.4,  1.7],
       [ 2.9,  3.6]])
'''


四、索引对象

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

obj = pd.Series(range(3), index=['a', 'b', 'c'])
index = obj.index
print index #Index(['a', 'b', 'c'], dtype='object')
print index[1:] #Index(['b', 'c'], dtype='object')

#Index对象是不可变的,因此用户不能对其进行修改
index[1] = 'd'  # TypeError

labels = pd.Index(np.arange(3))
print labels  #Int64Index([0, 1, 2], dtype='int64')

obj2 = pd.Series([1.5, -2.5, 0], index=labels)
print obj2
'''
0    1.5
1   -2.5
2    0.0
dtype: float64
'''
obj2.index is labels  #True

print frame3
'''
state  Nevada  Ohio
year               
2000      NaN   1.5
2001      2.4   1.7
2002      2.9   3.6
'''
print frame3.columns   #Index(['Nevada', 'Ohio'], dtype='object', name='state')

'Ohio' in frame3.columns #True
2003 in frame3.index #False

#​
obj = pd.Series(range(3), index=['a', 'b', 'c'])
index = obj.index
print index #Index(['a', 'b', 'c'], dtype='object')
print index[1:] #Index(['b', 'c'], dtype='object')

#Index对象是不可变的,因此用户不能对其进行修改
index[1] = 'd'  # TypeError

labels = pd.Index(np.arange(3))
print labels  #Int64Index([0, 1, 2], dtype='int64')

obj2 = pd.Series([1.5, -2.5, 0], index=labels)
print obj2
'''
0    1.5
1   -2.5
2    0.0
dtype: float64
'''
obj2.index is labels  #True

print frame3
'''
state  Nevada  Ohio
year               
2000      NaN   1.5
2001      2.4   1.7
2002      2.9   3.6
'''
print frame3.columns   #Index(['Nevada', 'Ohio'], dtype='object', name='state')

'Ohio' in frame3.columns #True
2003 in frame3.index #False

​#​
obj = pd.Series(range(3), index=['a', 'b', 'c'])
index = obj.index
print index #Index(['a', 'b', 'c'], dtype='object')
print index[1:] #Index(['b', 'c'], dtype='object')

#Index对象是不可变的,因此用户不能对其进行修改
index[1] = 'd'  # TypeError

labels = pd.Index(np.arange(3))
print labels  #Int64Index([0, 1, 2], dtype='int64')

obj2 = pd.Series([1.5, -2.5, 0], index=labels)
print obj2
'''
0    1.5
1   -2.5
2    0.0
dtype: float64
'''
obj2.index is labels  #True

print frame3
'''
state  Nevada  Ohio
year               
2000      NaN   1.5
2001      2.4   1.7
2002      2.9   3.6
'''
print frame3.columns   #Index(['Nevada', 'Ohio'], dtype='object', name='state')

'Ohio' in frame3.columns #True
2003 in frame3.index #False

​#与python的集合不同,pandas的Index可以包含重复的标签
dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar'])
print dup_labels           #Index(['foo', 'foo', 'bar', 'bar'], dtype='object')

 

五、重新索引

pandas对象的一个重要方法是reindex,其作用是创建一个新对象,它的数据符合新的索引。

obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
print obj
'''
d    4.5
b    7.2
a   -5.3
c    3.6
dtype: float64
'''
#用该Series的reindex将会根据新索引进行重排。如果某个索引值当前不存在,就引入缺失值。
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
'''
#对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。method选项即可达到此目的
obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
print obj3
'''
0      blue
2    purple
4    yellow
dtype: object
'''
obj3.reindex(range(6), method='ffill')
print obj3
'''
0      blue
1      blue
2    purple
3    purple
4    yellow
5    yellow
dtype: object
'''
#借助DataFrame,reindex可以修改(行)索引和列。
frame = pd.DataFrame(np.arange(9).reshape((3, 3)), 
                    index=['a', 'c', 'd'],columns=['Ohio', 'Texas', 'California'])
print frame
'''
   Ohio  Texas  California
a     0      1           2
c     3      4           5
d     6      7           8
'''
frame2 = frame.reindex(['a', 'b', 'c', 'd'])
print frame2
'''
   Ohio  Texas  California
a   0.0    1.0         2.0
b   NaN    NaN         NaN
c   3.0    4.0         5.0
d   6.0    7.0         8.0
'''
states = ['Texas', 'Utah', 'California']
frame.reindex(columns=states)
'''
   Texas  Utah  California
a      1   NaN           2
c      4   NaN           5
d      7   NaN           8
'''

六、丢弃指定轴上的项

丢弃某条轴上的一个或多个项很简单,只要有一个索引数组或列表即可。由于需要执行一些数据整理和集合逻辑,所以drop方法返回的是一个在指定轴上删除了指定值的新对象。

obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
print obj
'''
a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64
'''
new_obj = obj.drop('c')
print new_obj
'''
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64
'''
obj.drop(['d', 'c'])
'''
a    0.0
b    1.0
e    4.0
dtype: float64
'''

#对于DataFrame,可以删除任意轴上的索引值。
data = pd.DataFrame(np.arange(16).reshape((4, 4)), 
                    index=['Ohio', 'Colorado', 'Utah', 'New York'],
                    columns=['one', 'two', 'three', 'four'])
print data
'''
one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
'''
#用标签序列调用drop会从行标签(axis 0)删除值:
data.drop(['Colorado', 'Ohio'])
print data
'''
          one  two  three  four
Utah        8    9     10    11
New York   12   13     14    15
'''
#通过传递axis=1或axis='columns'可以删除列的值:
data.drop('two', axis=1)
print data
'''
          one  three  four
Ohio        0      2     3
Colorado    4      6     7
Utah        8     10    11
New York   12     14    15
'''
data.drop(['two', 'four'], axis='columns')
print data
'''
          one  three
Ohio        0      2
Colorado    4      6
Utah        8     10
New York   12     14
'''

七、索引、选取和过滤

obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
print obj
'''
a    0.0
b    1.0
c    2.0
d    3.0
dtype: float64
'''
print obj['b'] #1.0
print obj[1] #1.0
print obj[2:4]
'''
c    2.0
d    3.0
dtype: float64
'''
print obj[['b', 'a', 'd']]
'''
b    1.0
a    0.0
d    3.0
dtype: float64
'''
print obj[[1, 3]]
'''
b    1.0
d    3.0
dtype: float64
'''

#利用标签的切片运算与普通的Python切片运算不同,其末端是包含的:
print obj['b':'c']
'''
b    1.0
c    2.0
dtype: float64
'''

#用一个值或序列对DataFrame进行索引其实就是获取一个或多个列:
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
                index=['Ohio', 'Colorado', 'Utah', 'New York'],
                columns=['one', 'two', 'three', 'four'])
print data
'''
            one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
'''
print data['two']
'''
Ohio         1
Colorado     5
Utah         9
New York    13
Name: two, dtype: int64
'''
print data[data['three'] > 5]
'''
          one  two  three  four
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
'''
print data < 5
'''
one    two  three   four
Ohio       True   True   True   True
Colorado   True  False  False  False
Utah      False  False  False  False
New York  False  False  False  False
'''
print data[data < 5] = 0
'''
one  two  three  four
Ohio        0    0      0     0
Colorado    0    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
'''

八、用loc和iloc进行选取

对于DataFrame的行的标签索引,我引入了特殊的标签运算符loc和iloc。它们可以让你用类似NumPy的标记,使用轴标签(loc)或整数索引(iloc),从DataFrame选择行和列的子集。

print data.loc['Colorado', ['two', 'three']]
'''
two      5
three    6
Name: Colorado, dtype: int64
'''
#用iloc和整数进行选取
print data.iloc[2]
'''
one       8
two       9
three    10
four     11
Name: Utah, dtype: int64
'''
print data.iloc[[1, 2], [3, 0, 1]]
'''
          four  one  two
Colorado     7    0    5
Utah        11    8    9
'''

九、算术运算和数据对齐 

pandas最重要的一个功能是,它可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。对于有数据库经验的用户,这就像在索引标签上进行自动外连接。

s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],index=['a', 'c', 'e', 'f', 'g'])
#自动的数据对齐操作在不重叠的索引处引入了NA值。缺失值会在算术运算过程中传播。
print s1 + s2
'''
a    5.2
c    1.1
d    NaN
e    0.0
f    NaN
g    NaN
dtype: float64
'''
df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'),
                index=['Ohio', 'Texas', 'Colorado'])

Idf2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
                index=['Utah', 'Ohio', 'Texas', 'Oregon'])
print df1 + df2 #因为'c'和'e'列均不在两个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
'''


十、在算术方法中填充值

在对不同索引的对象进行算术运算时,你可能希望当一个对象中某个轴标签在另一个对象中找不到时填充一个特殊值(比如0)。

df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)),columns=list('abcd'))
df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)),columns=list('abcde'))
df2.loc[1, 'b'] = np.nan
print df2
'''
a     b     c     d     e
0   0.0   1.0   2.0   3.0   4.0
1   5.0   NaN   7.0   8.0   9.0
2  10.0  11.0  12.0  13.0  14.0
3  15.0  16.0  17.0  18.0  19.0
'''
print df1 + df2  #将它们相加时,没有重叠的位置就会产生NA值
'''
      a     b     c     d   e
0   0.0   2.0   4.0   6.0 NaN
1   9.0   NaN  13.0  15.0 NaN
2  18.0  20.0  22.0  24.0 NaN
3   NaN   NaN   NaN   NaN NaN
'''
print df1.add(df2, fill_value=0) #使用df1的add方法,传入df2以及一个fill_value参数
'''
a     b     c     d     e
0   0.0   2.0   4.0   6.0   4.0
1   9.0   5.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
'''

十一、DataFrame和Series之间的运算 

跟不同维度的NumPy数组一样,DataFrame和Series之间算术运算也是有明确规定的。

frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
                                  columns=list('bde'),
                                  index=['Utah', 'Ohio', 'Texas', 'Oregon'])
series = frame.iloc[0]
print frame - series
'''
          b    d    e
Utah    0.0  0.0  0.0
Ohio    3.0  3.0  3.0
Texas   6.0  6.0  6.0
Oregon  9.0  9.0  9.0
'''
#如果某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集
series2 = pd.Series(range(3), index=['b', 'e', 'f'])
print frame + series2
'''
          b   d     e   f
Utah    0.0 NaN   3.0 NaN
Ohio    3.0 NaN   6.0 NaN
Texas   6.0 NaN   9.0 NaN
Oregon  9.0 NaN  12.0 NaN
'''
#如果你希望匹配行且在列上广播,则必须使用算术运算方法。
series3 = frame['d']
print frame.sub(series3, axis='index')
'''
          b    d    e
Utah   -1.0  0.0  1.0
Ohio   -1.0  0.0  1.0
Texas  -1.0  0.0  1.0
Oregon -1.0  0.0  1.0
'''
#传入的轴号就是希望匹配的轴。在本例中,我们的目的是匹配DataFrame的行索引(axis='index' or axis=0)并进行广播。

十二、函数应用和映射

NumPy的ufuncs(元素级数组方法)也可用于操作pandas对象。

frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'),
                             index=['Utah', 'Ohio', 'Texas', 'Oregon'])
print frame
'''
b         d         e
Utah   -0.204708  0.478943 -0.519439
Ohio   -0.555730  1.965781  1.393406
Texas   0.092908  0.281746  0.769023
Oregon  1.246435  1.007189 -1.296221
'''
print np.abs(frame)
'''
b         d         e
Utah    0.204708  0.478943  0.519439
Ohio    0.555730  1.965781  1.393406
Texas   0.092908  0.281746  0.769023
Oregon  1.246435  1.007189  1.296221
'''
#另一个常见的操作是,将函数应用到由各列或行所形成的一维数组上。DataFrame的apply方法即可实现此功能.
f = lambda x: x.max() - x.min()
print frame.apply(f)#这里的函数f,计算了一个Series的最大值和最小值的差,
                    #在frame的每列都执行了一次。结果是一个Series,使用frame的列作为索引
'''
b    1.802165
d    1.684034
e    2.689627
dtype: float64
'''
#如果传递axis='columns'到apply,这个函数会在每行执行.
frame.apply(f, axis='columns')
'''
Utah      0.998382
Ohio      2.521511
Texas     0.676115
Oregon    2.542656
dtype: float64
'''

十三、排序和排名

根据条件对数据集排序(sorting)也是一种重要的内置运算。要对行或列索引进行排序(按字典顺序),可使用sort_index方法,它将返回一个已排序的新对象。

obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
print obj.sort_index()
'''
a    1
b    2
c    3
d    0
dtype: int64
'''
frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
                                index=['three', 'one'],
                                columns=['d', 'a', 'b', 'c'])
print frame.sort_index()
'''
       d  a  b  c
one    4  5  6  7
three  0  1  2  3
'''
print frame.sort_index(axis=1)
'''
       a  b  c  d
three  1  2  3  0
one    5  6  7  4
'''

#若要按值对Series进行排序,可使用其sort_values方法。
obj = pd.Series([4, 7, -3, 2])
print obj
'''
2   -3
3    2
0    4
1    7
dtype: int64
'''
#在排序时,任何缺失值默认都会被放到Series的末尾。
print obj.sort_values()
'''
4   -3.0
5    2.0
0    4.0
2    7.0
1    NaN
3    NaN
dtype: float64
'''
#排序一个DataFrame时,你可能希望根据一个或多个列中的值进行排序。
#将一个或多个列的名字传递给sort_values的by选项即可达到该目的
frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
print frame
'''
   a  b
0  0  4
1  1  7
2  0 -3
3  1  2
'''
print frame.sort_values(by='b')
'''
   a  b
2  0 -3
3  1  2
0  0  4
1  1  7
'''

十四、汇总和计算描述统计

pandas对象拥有一组常用的数学和统计方法。它们大部分都属于约简和汇总统计,用于从Series中提取单个值(如sum或mean)或从DataFrame的行或列中提取一个Series。跟对应的NumPy数组方法相比,它们都是基于没有缺失数据的假设而构建的。

df = pd.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
'''
    one  two
a  1.40  NaN
b  7.10 -4.5
c   NaN  NaN
d  0.75 -1.3
'''
print df.sum()
'''
one    9.25
two   -5.80
dtype: float64
'''

#传入axis='columns'或axis=1将会按行进行求和运算
print df.sum(axis=1)
'''
a    1.40
b    2.60
c     NaN
d   -0.55
'''
#NA值会自动被排除,除非整个切片(这里指的是行或列)都是NA。通过skipna选项可以禁用该功能:

print df.mean(axis='columns', skipna=False)
'''
a      NaN
b    1.300
c      NaN
d   -0.275
dtype: float64
'''

数据加载、存储与文件格式 

十五、读写文本格式的数据

pandas提供了一些用于将表格型数据读取为DataFrame对象的函数。这边我将只介绍读取csv文件。

!cat examples/ex1.csv  #cat命令 查看csv文件内容
a,b,c,d,message
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
#read_csv
df = pd.read_csv('examples/ex1.csv')
print df
'''
   a   b   c   d message
0  1   2   3   4   hello
1  5   6   7   8   world
2  9  10  11  12     foo
'''
#read_table
df1 = pd.read_table('examples/ex1.csv', sep=',')
print df1
'''
   a   b   c   d message
0  1   2   3   4   hello
1  5   6   7   8   world
2  9  10  11  12     foo
'''
#to_csv方法,我们可以将数据写到一个以逗号分隔的文件中
'''
data
  something  a   b     c   d message
0       one  1   2   3.0   4     NaN
1       two  5   6   NaN   8   world
2     three  9  10  11.0  12     foo
data.to_csv('examples/out.csv')
'''
'''
 !cat examples/out.csv
,something,a,b,c,d,message
0,one,1,2,3.0,4,
1,two,5,6,,8,world
2,three,9,10,11.0,12,foo
'''
#read txt
'''
data4.txt
    A    B    C
a   1    2    3
b   4    5    6
'''
x = pd.read_table('data4.txt', sep='\s+') # sep:分隔的正则表达式,表示空格
print x
'''
   A  B  C
a  1  2  3
b  4  5  6
'''

数据清洗和准备

十六、处理缺失数据

缺失数据在pandas中呈现的方式有些不完美,但对于大多数用户可以保证功能正常。对于数值数据,pandas使用浮点值NaN(Not a Number)表示缺失数据。

string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
print string_data
'''
0     aardvark
1    artichoke
2          NaN
3      avocado
dtype: object
'''
print string_data.isnull()
'''
0    False
1    False
2     True
3    False
dtype: bool
'''

十七、滤除缺失数据

过滤掉缺失数据的办法有很多种。你可以通过pandas.isnull或布尔索引的手工方法,但dropna可能会更实用一些。对于一个Series,dropna返回一个仅含非空数据和索引值的Series。

from numpy import nan as NA
data = pd.Series([1, NA, 3.5, NA, 7])
print data.dropna()  #== data[data.notnull()]
'''
0    1.0
2    3.5
4    7.0
dtype: float64
'''
#对于DataFrame对象,dropna默认丢弃任何含有缺失值的行
data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA],[NA, NA, NA], [NA, 6.5, 3.]])
cleaned = data.dropna()
print data
print cleaned
'''
     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

     0    1    2
0  1.0  6.5  3.0
'''
data.dropna(how='all') #传入how='all'将只丢弃全为NA的那些行
print data
'''
     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.dropna(axis=1, how='all')
print 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
'''
#另一个滤除DataFrame行的问题涉及时间序列数据。假设你只想留下一部分观测数据,
#可以用thresh参数实现此目的。
df = pd.DataFrame(np.random.randn(7, 3))
df.iloc[:4, 1] = NA
df.iloc[:2, 2] = NA
print df
'''
0         1         2
0 -0.204708       NaN       NaN
1 -0.555730       NaN       NaN
2  0.092908       NaN  0.769023
3  1.246435       NaN -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741
'''
df.dropna(thresh=2)
'''
0         1         2
2  0.092908       NaN  0.769023
3  1.246435       NaN -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741
'''

 十九、填充缺失数据

你可能不想滤除缺失数据(有可能会丢弃跟它有关的其他数据),而是希望通过其他方式填补那些“空洞”。对于大多数情况而言,fillna方法是最主要的函数。通过一个常数调用fillna就会将缺失值替换为那个常数值。

df.fillna(0)
print df
'''
0         1         2
0 -0.204708  0.000000  0.000000
1 -0.555730  0.000000  0.000000
2  0.092908  0.000000  0.769023
3  1.246435  0.000000 -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741
'''
#若是通过一个字典调用fillna,就可以实现对不同的列填充不同的值:
df.fillna({1: 0.5, 2: 0})
'''
0         1         2
0 -0.204708  0.500000  0.000000
1 -0.555730  0.500000  0.000000
2  0.092908  0.500000  0.769023
3  1.246435  0.500000 -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741
'''
#fillna默认会返回新对象,但也可以对现有对象进行就地修改
 _ = df.fillna(0, inplace=True)
'''
0         1         2
0 -0.204708  0.000000  0.000000
1 -0.555730  0.000000  0.000000
2  0.092908  0.000000  0.769023
3  1.246435  0.000000 -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741
'''
#只要有些创新,你就可以利用fillna实现许多别的功能。
data = pd.Series([1., NA, 3.5, NA, 7])
data.fillna(data.mean())
'''
0    1.000000
1    3.833333
2    3.500000
3    3.833333
4    7.000000
dtype: float64
'''

二十、替换值

利用fillna方法填充缺失数据可以看做值替换的一种特殊情况。replace则提供了一种实现该功能的更简单、更灵活的方式。

data = pd.Series([1., -999., 2., -999., -1000., 3.])
data.replace(-999, np.nan)
'''
0       1.0
1       NaN
2       2.0
3       NaN
4   -1000.0
5       3.0
dtype: float64
'''
data.replace([-999, -1000], np.nan)
'''
0    1.0
1    NaN
2    2.0
3    NaN
4    NaN
5    3.0
dtype: float64
'''
data.replace([-999, -1000], [np.nan, 0])
'''
0    1.0
1    NaN
2    2.0
3    NaN
4    0.0
5    3.0
dtype: float64
'''

二十一、移除重复数据

data = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'], 'k2': [1, 1, 2, 3, 3, 4, 4]})
print data
'''
    k1  k2
0  one   1
1  two   1
2  one   2
3  two   3
4  one   3
5  two   4
6  two   4
'''
#DataFrame的duplicated方法返回一个布尔型Series,表示各行是否是重复行
data.duplicated()
'''
0    False
1    False
2    False
3    False
4    False
5    False
6     True
dtype: bool
'''
#还有一个与此相关的drop_duplicates方法,它会返回一个DataFrame,重复的数组会标为False
data.drop_duplicates()
'''
    k1  k2
0  one   1
1  two   1
2  one   2
3  two   3
4  one   3
5  two   4
'''
#以指定部分列进行重复项判断
data['v1'] = range(7)
data.drop_duplicates(['k1'])
'''
    k1  k2  v1
0  one   1   0
1  two   1   1
'''

总结

        借鉴书籍《利用Python进行数据分析·第2版》。本文只是列举常用的操作,后期遇到会继续添加。

        pandas书籍:《利用Python进行数据分析·第2版》《Pandas Cookbook》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值