利用python进行数据分析-pandas入门3

1.函数应用和映射

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

frame=DataFrame(np.random.randn(4,3),columns=list('bde'),index=['Uath','Ohio','Texas','Oregon'])
print frame
print np.abs(frame)

结果为:

               b         d         e
Uath    1.187068  1.589404  0.328555
Ohio   -0.040634  1.489594 -0.453027
Texas   0.362667  0.601500  2.177313
Oregon  0.019020 -0.315751 -0.480646
               b         d         e
Uath    1.187068  1.589404  0.328555
Ohio    0.040634  1.489594  0.453027
Texas   0.362667  0.601500  2.177313
Oregon  0.019020  0.315751  0.480646

另一个常见的操作是,将函数应用到由各列或行所形成的一维数组上。DataFrame的apply方法即可实现此功能

f=lambda x:x.max()-x.min()
print frame.apply(f)
print frame.apply(f,axis=1)

结果为:

b    0.605155
d    2.173279
e    2.737098
dtype: float64
Uath      1.913344
Ohio      0.302252
Texas     1.663901
Oregon    1.654397
dtype: float64

许多最为常见的数组统计功能都能被实现成DataFrame的方法(比如sum和mean),因此无需使用apply方法

除标量值外,传递给apply的函数还可以返回由多个值组成的Series

def f(x):
    return Series([x.min(),x.max()],index=['min','max'])
    
print frame.apply(f)

结果为:

            b         d         e
min -1.878553 -1.339043 -2.638153
max  1.051156  1.322494  0.242260

此外,元素级的Python函数也是可以用的。如你想得到frame中各个浮点值的格式化字符串,可以使用applymap

format=lambda x:'%.2f' % x
print frame.applymap(format)

结果为:

            b      d      e
Uath     0.27   0.94   0.73
Ohio    -0.81   0.78  -1.04
Texas    1.00   0.64   0.61
Oregon   0.55  -0.17  -0.40

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

print frame['e'].map(format)

结果为:

Uath      0.17
Ohio      2.22
Texas     0.58
Oregon    0.18
Name: e, dtype: object


2.排序和排名

要对行或列索引进行排序(按字典排序),可使用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

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

frame2=DataFrame(np.arange(8).reshape(2,4),index=['three','one'],columns=['d','a','b','c'])
print frame2.sort_index()
print frame2.sort_index(axis=1)

结果为:

       d  a  b  c
one    4  5  6  7
three  0  1  2  3
       a  b  c  d
three  1  2  3  0
one    5  6  7  4

数据默认是按照升序排序的,也可以降序排序

print frame2.sort_index(axis=1,ascending=False)

结果为:

       d  c  b  a
three  0  3  2  1
one    4  7  6  5

若要按值对Series进行排序,可使用其order方法

obj2=Series([4,7,-3,2])
print obj2.order()

结果为:

2   -3
3    2
0    4
1    7

在排序时,任何缺失值默认都会被放到Series末尾

obj3=Series([4,np.nan,7,np.nan,-3,2])
print obj3.order()

结果为:

4    -3
5     2
0     4
2     7
1   NaN
3   NaN
dtype: float64

在DataFrame上,你可能希望根据一个或多个列中的值进行排序。将一个或多个列的名字传递给by选项即可达到该目的

frame3=DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]})
print frame3
print frame3.sort_index(by='b')

结果为:

   a  b
0  0  4
1  1  7
2  0 -3
3  1  2
   a  b
2  0 -3
3  1  2
0  0  4
1  1  7

要根据多个列进行排序,传入名称的列表即可

print frame3.sort_index(by=['a','b'])

结果为:

   a  b
2  0 -3
0  0  4
3  1  2
1  1  7

排名(ranking)跟排序关系密切,且它会增设一个排名值(从1开始,一直到数组中有效数据的数量)。默认情况下,rank是通过“为各组分配一个平均排名”的方式破坏平级关系的

obj4=Series([7,-5,7,4,2,0,4])
print obj4.rank()

结果为:

0    6.5
1    1.0
2    6.5
3    4.5
4    3.0
5    2.0
6    4.5

也可以根据值在原数据中出现的顺序给出排名

print obj4.rank(method='first')

结果为:

0    6
1    1
2    7
3    4
4    3
5    2
6    5
dtype: float64

也可以按降序进行排名

print obj4.rank(method='max',ascending=False)

结果为:

0    2
1    7
2    2
3    4
4    5
5    6
6    4
dtype: float64

利用python进行数据分析-pandas入门3_第1张图片


3.带有重复值的轴索引

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

obj5=Series(range(5),index=['a','a','b','b','c'])
print obj5
print obj5.index.is_unique

结果为:

a    0
a    1
b    2
b    3
c    4
dtype: int64
False

如果某个索引对应多个值,则返回一个Series

print obj5['a']

结果为:

a    0
a    1
dtype: int64

对DataFrame进行索引时也是如此

df=DataFrame(np.arange(12).reshape(4,3),index=['a','a','b','b'])
print df.ix['b']

结果为:

   0   1   2
b  6   7   8
b  9  10  11


4.汇总和计算描述统计

df2=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 df2
print df2.sum()
print df2.sum(axis=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    0.00
d   -0.55
dtype: float64

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

print df2.sum(axis=1,skipna=False)

结果为:

a     NaN
b    2.60
c     NaN
d   -0.55
dtype: float64

利用python进行数据分析-pandas入门3_第2张图片

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

print df2.idxmax()

结果为:

one    b
two    d
dtype: object

另一些方法则是累计型的

print df2.cumsum()

结果为:

    one  two
a  1.40  NaN
b  8.50 -4.5
c   NaN  NaN
d  9.25 -5.8

还有一种方法,它既不是约简型也不是累计型。describe就是一个例子,它用于一次性产生多个汇总统计

print df2.describe()

结果为:

            one       two
count  3.000000  2.000000
mean   3.083333 -2.900000
std    3.493685  2.262742
min    0.750000 -4.500000
25%    1.075000 -3.700000
50%    1.400000 -2.900000
75%    4.250000 -2.100000
max    7.100000 -1.300000

利用python进行数据分析-pandas入门3_第3张图片

利用python进行数据分析-pandas入门3_第4张图片


5.相关系数与协方差

import pandas.io.data as web

all_data={}
for ticker in ['AAPL','IBM','MSFT','GOOG']:
    all_data[ticker]=web.get_data_yahoo(ticker,'1/1/2000','1/1/2010')
    
price=DataFrame({tic:data['Adj Close']
                    for tic,data in all_data.iteritems()})
volume=DataFrame({tic:data['Volume']
                    for tic,data in all_data.iteritems()})
                        
returns=price.pct_change()
print returns.tail()

结果为:

                AAPL      GOOG       IBM      MSFT
Date                                              
2009-12-24  0.034339  0.011117  0.004385  0.002587
2009-12-28  0.012294  0.007098  0.013326  0.005484
2009-12-29 -0.011861 -0.005571 -0.003477  0.007058
2009-12-30  0.012147  0.005376  0.005461 -0.013699
2009-12-31 -0.004300 -0.004416 -0.012597 -0.015504

Series的corr方法用于计算两个Series中重叠、非NA的、按索引对齐的值的相关系数。与此类似,cov用于计算协方差

print returns.MSFT.corr(returns.IBM)
print returns.MSFT.cov(returns.IBM)

结果为:

0.495979684549
0.000215957648434

DataFrame的corr和cov方法将以DataFrame的形式返回完整的相关系数与协方差矩阵

print returns.corr()
print returns.cov()

结果为:

          AAPL      GOOG       IBM      MSFT
AAPL  1.000000  0.470676  0.410011  0.424305
GOOG  0.470676  1.000000  0.390689  0.443587
IBM   0.410011  0.390689  1.000000  0.495980
MSFT  0.424305  0.443587  0.495980  1.000000
          AAPL      GOOG       IBM      MSFT
AAPL  0.001027  0.000303  0.000252  0.000309
GOOG  0.000303  0.000580  0.000142  0.000205
IBM   0.000252  0.000142  0.000367  0.000216
MSFT  0.000309  0.000205  0.000216  0.000516

利用DataFrame的corrwith方法,你可以计算其列或行跟另一个Series或DataFrame之间的相关系数。传入一个Series将会返回一个相关系数值Series(针对各列进行计算)

print returns.corrwith(returns.IBM)

结果为:

AAPL    0.410011
GOOG    0.390689
IBM     1.000000
MSFT    0.495980
dtype: float64

传入一个DataFrame则会计算按列名配对的相关系数。这里,计算百分比变化与成交量的相关系数

print returns.corrwith(volume)

结果为:

AAPL   -0.057549
GOOG    0.062647
IBM    -0.007892
MSFT   -0.014245
dtype: float64

传入axis=1即可按行进行计算。无论如何,在计算相关系数之前,所有的数据项都会按标签对齐


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

obj6=Series(['c','a','d','a','a','b','b','c','c'])
uniques=obj6.unique()
print uniques

结果为:

['c' 'a' 'd' 'b']

返回的唯一值是未排序的,可以对结果再次进行排序(uniques.sort())。value_counts计算一个Series中各值出现的频率

print obj6.value_counts()

结果为:

c    3
a    3
b    2
d    1
dtype: int64

value_counts还有一个顶级pandas方法,可用于任何数组或序列

print pd.value_counts(obj6.values,sort=False)

结果为:

a    3
c    3
b    2
d    1
dtype: int64

isin,它用于判断矢量化集合的成员资格,可用于选取Series中或DataFrame列中数据的子集

mask=obj6.isin(['b','c'])
print mask
print obj6[mask]

结果为:

0     True
1    False
2    False
3    False
4    False
5     True
6     True
7     True
8     True
dtype: bool
0    c
5    b
6    b
7    c
8    c
dtype: object

利用python进行数据分析-pandas入门3_第5张图片

有时,你希望得到DataFrame中多个相关列的一张柱状图

data2=DataFrame({'Qu1':[1,3,4,3,4],
                 'Qu2':[2,3,1,2,3],
                 'Qu3':[1,5,2,4,4]})
print data2
result=data2.apply(pd.value_counts).fillna(0)
print result

结果为:

   Qu1  Qu2  Qu3
0    1    2    1
1    3    3    5
2    4    1    2
3    3    2    4
4    4    3    4
   Qu1  Qu2  Qu3
1    1    1    1
2    0    2    1
3    2    2    0
4    2    0    2
5    0    0    1


7.处理丢失数据

pandas使用浮点值NAN表示浮点和非浮点数组中的缺失数据,它只是一个便于被检测出来的标记而已

string_data=Series(['aardvark','artichoke',np.nan,'avocado'])
print string_data
print string_data.isnull()

结果为:

0     aardvark
1    artichoke
2          NaN
3      avocado
dtype: object
0    False
1    False
2     True
3    False
dtype: bool

python内置的None值也会被当做NA处理

string_data[0]=None
print string_data.isnull()

结果为:

0     True
1    False
2     True
3    False
dtype: bool

利用python进行数据分析-pandas入门3_第6张图片


8.滤除缺失数据

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

from numpy import nan as NA

data=Series([1,NA,3.5,NA,7])
print data.dropna()
print data[data.notnull()]

结果为:

0    1.0
2    3.5
4    7.0
dtype: float64
0    1.0
2    3.5
4    7.0
dtype: float64

对于DataFrame对象,事情就有点复杂了。你可能希望丢弃全NA或含有NA的行或列。dropna默认丢弃任何含有缺失值的行

data3=DataFrame([[1,6.5,3],[1,NA,NA],[NA,NA,NA],[NA,6.5,3]])
print data3
cleaned=data3.dropna()
print cleaned

结果为:

    0    1   2
0   1  6.5   3
1   1  NaN NaN
2 NaN  NaN NaN
3 NaN  6.5   3
   0    1  2
0  1  6.5  3

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

print data3.dropna(how='all')

结果为:

    0    1   2
0   1  6.5   3
1   1  NaN NaN
3 NaN  6.5   3

要用这种方式丢弃列,只需传入axis=1即可

data3[4]=NA
print data3
print data3.dropna(axis=1,how='all')

结果为:

    0    1   2   4
0   1  6.5   3 NaN
1   1  NaN NaN NaN
2 NaN  NaN NaN NaN
3 NaN  6.5   3 NaN
    0    1   2
0   1  6.5   3
1   1  NaN NaN
2 NaN  NaN NaN
3 NaN  6.5   3

另一个滤除DataFrame行的问题涉及到时间序列数据。假设你只想留下一部分观测数据,可以用thresh参数实现此目的

df3=DataFrame(np.random.randn(7,3))
df3.ix[:4,1]=NA
df3.ix[:2,2]=NA
print df3
print df3.dropna(thresh=3)

结果为:

          0         1         2
0  2.399544       NaN       NaN
1  0.430949       NaN       NaN
2 -1.083213       NaN       NaN
3 -0.431232       NaN  0.756593
4  0.529114       NaN -0.595716
5  1.444382 -0.195083 -0.930979
6 -1.412920 -0.934195  2.861213
          0         1         2
5  1.444382 -0.195083 -0.930979
6 -1.412920 -0.934195  2.861213


9.填充缺失数据

fillna方法是最主要的函数

print df3.fillna(0)
print df3.fillna({1:0.5,3:-1})

结果为:

          0                1               2
0 -0.034171  0.000000  0.000000
1 -0.115502  0.000000  0.000000
2  0.308157  0.000000  0.000000
3  1.367718  0.000000 -0.306751
4 -1.360234  0.000000  0.999463
5 -0.148457  0.156416 -2.017497
6 -0.408602  0.403680 -1.352914
          0                1                2
0 -0.034171  0.500000       NaN
1 -0.115502  0.500000       NaN
2  0.308157  0.500000       NaN
3  1.367718  0.500000 -0.306751
4 -1.360234  0.500000  0.999463
5 -0.148457  0.156416 -2.017497
6 -0.408602  0.403680 -1.352914

fillna默认会返回新对象,但也可以对现有对象进行就地修改

_=df3.fillna(0,inplace=True)
print df3

结果为:

          0                 1               2
0 -1.901323  0.000000  0.000000
1 -0.431574  0.000000  0.000000
2  1.452733  0.000000  0.000000
3  0.013765  0.000000  0.572696
4  0.121601  0.000000 -0.972343
5  0.411238 -0.023716  0.827292
6  0.266131  0.706082  0.859971

对reindex有效的那些插值方法也可用于fillna

df4=DataFrame(np.random.randn(6,3))
df4.ix[2:,1]=NA
df4.ix[4:,2]=NA
print df4
print df4.fillna(method='ffill')
print df4.fillna(method='ffill',limit=2)

结果为:

          0                 1              2
0  0.132548  0.581560  0.539203
1  0.250056  0.676504 -0.645744
2  0.760809       NaN  1.073846
3 -0.480362       NaN  0.221771
4 -0.600295       NaN       NaN
5  0.005458       NaN       NaN
          0                 1              2
0  0.132548  0.581560  0.539203
1  0.250056  0.676504 -0.645744
2  0.760809  0.676504  1.073846
3 -0.480362  0.676504  0.221771
4 -0.600295  0.676504  0.221771
5  0.005458  0.676504  0.221771
          0                  1              2
0  0.132548  0.581560  0.539203
1  0.250056  0.676504 -0.645744
2  0.760809  0.676504  1.073846
3 -0.480362  0.676504  0.221771
4 -0.600295       NaN  0.221771
5  0.005458       NaN  0.221771

利用python进行数据分析-pandas入门3_第7张图片


10.层次化索引

它使你能以低纬度形式处理高纬度数据

data4=Series(np.random.randn(10),index=[['a','a','a','b','b','b','c','c','d','d'],
              [1,2,3,1,2,3,1,2,2,3]])
print data4

结果为:

a  1   -0.219090
   2   -1.372102
   3    1.108223
b  1   -0.796361
   2    1.175877
   3    0.520666
c  1    1.058822
   2    1.325842
d  2   -0.040458
   3    0.205163
dtype: float64

这就是带有MultiIndex索引的Series的格式化输出形式。索引之间的“间隔”表示“直接使用上面的标签”

print data4.index

结果为:

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, 1, 2]])

对于一个层次化索引的对象,选取数据子集的操作很简单

print data4['b']

结果为:

1   -0.094394
2    0.531658
3   -0.159814
dtype: float64

print data4['b':'c']
print data4.ix[['b','d']]

结果为:

b  1   -1.336168
   2    0.074839
   3   -0.615861
c  1   -0.349232
   2   -0.024671
dtype: float64
b  1   -1.336168
   2    0.074839
   3   -0.615861
d  2    1.444744
   3   -0.824043
dtype: float64

可以通过其unstack方法被重新安排到一个DataFrame中

print data4.unstack()

结果为:

          1         2         3
a  1.483774  0.221626  0.085326
b  0.354429 -1.018716  0.423129
c -1.038540  2.103571       NaN
d       NaN  0.596784  1.500782

unstack的逆运算是stack

print data4.unstack().stack()

结果为:

a  1   -0.718105
   2    0.766081
   3   -0.221549
b  1   -0.521521
   2   -1.252716
   3   -0.329751
c  1    1.912822
   2   -0.794359
d  2    1.432758
   3    1.244745
dtype: float64

对于一个DataFrame,每条轴上都可以有分层索引

frame4=DataFrame(np.arange(12).reshape((4,3)),
                 index=[['a','a','b','b'],[1,2,1,2]],
                 columns=[['Ohio','Ohio','Colorado'],
                          ['Green','Red','Green']])
print frame4
frame4.index.names=['key1','key2']
frame4.columns.names=['state','color']
print frame4

结果为:

     Ohio     Colorado
    Green Red    Green
a 1     0   1        2
  2     3   4        5
b 1     6   7        8
  2     9  10       11
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


11.重排分级排序

swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化)

print frame4.swaplevel('key1','key2')

结果为:

state      Ohio     Colorado
color     Green Red    Green
key2 key1                   
1    a        0   1        2
2    a        3   4        5
1    b        6   7        8
2    b        9  10       11

而sortlevel则根据单个级别中的值对数据进行排序。交换级别时,常常也会用到sortlevel,这样最终结果就是有序的了

print frame4.sortlevel(1)
print frame4.swaplevel(0,1).sortlevel(0)

结果为:

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
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


12.根据级别汇总统计

print frame4.sum(level='key2')
print frame4.sum(level='color',axis=1)

结果为:

state  Ohio     Colorado
color Green Red    Green
key2                    
1         6   8       10
2        12  14       16
color      Green  Red
key1 key2            
a    1         2    1
     2         8    4
b    1        14    7
     2        20   10


13.使用DataFrame的列

frame5=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 frame5

结果为:

   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

frame5=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 frame5
frame6=frame5.set_index(['c','d'])
print frame6

结果为:

   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
       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

默认情况下,那些列会从DataFrame中移除,但也可以将其保留下来

print frame5.set_index(['c','d'],drop=False)

结果为:

       a  b    c  d
c   d              
one 0  0  7  one  0
    1  1  6  one  1
    2  2  5  one  2
two 0  3  4  two  0
    1  4  3  two  1
    2  5  2  two  2
    3  6  1  two  3

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

print frame6.reset_index()

结果为:

     c  d  a  b
0  one  0  0  7
1  one  1  1  6
2  one  2  2  5
3  two  0  3  4
4  two  1  4  3
5  two  2  5  2
6  two  3  6  1

你可能感兴趣的:(python)