您的位置:首页 > 编程语言 > Python开发

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

2016-06-12 15:49 1051 查看
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



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



有些方法(如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





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



有时,你希望得到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



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





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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据分析 pandas python