数据分析之四:pandas库之索引对象和数学统计

1. pandas的索引对象


任何数组都有一个Index对象,可以为DataFrame设置各种各样的Index,如DatetimeIndex可以用来表示时间戳,MultiIndex可以表示层次索引,这些Index的基类是Index,可以通过以下方式查看Index:

In [227]: frame
Out[227]: 
   0  1  2
0  1  1  1
1  2  2  2
2  3  3  3

# 此DataFrame的索引是RangeIndex类型
In [228]: frame.index
Out[228]: RangeIndex(start=0, stop=3, step=1)

# 可以通过以下方式修改索引
In [230]: frame.index = ['a','b','c']

In [231]: frame
Out[231]: 
   0  1  2
a  1  1  1
b  2  2  2
c  3  3  3

In [232]: frame.index
Out[232]: Index([u'a', u'b', u'c'], dtype='object')

# 但是不可以这样,因为Index对象不支持这种修改方式
In [233]: idx = frame.index

In [234]: idx[0] = 'A'

1.1. 重新索引


In [258]: arr = Series(randn(4), index=['b', 'c', 'a', 'd'])

In [259]: arr
Out[259]: 
b    0.048503
c   -2.836523
a    0.231643
d    1.272932
dtype: float64


# 重新索引后,索引值跟着索引改变了位置
In [260]: arr1 = arr.reindex(['a', 'b', 'c', 'd', 'e'])

In [261]: arr1
Out[261]: 
a    0.231643
b    0.048503
c   -2.836523
d    1.272932
e         NaN
dtype: float64

In [264]: frame = DataFrame(np.arange(9).reshape((3,3)), columns=['b', 'a', 'c'])

In [265]: frame
Out[265]: 
   b  a  c
0  0  1  2
1  3  4  5
2  6  7  8

# 同样,可以重排列索引,也可以同时对行和列重排
In [266]: frame.reindex(columns=['a', 'b', 'c', 'd'])
Out[266]: 
   a  b  c   d
0  1  0  2 NaN
1  4  3  5 NaN
2  7  6  8 NaN

1.2. 通过索引删除


# 先来看缺省值的删除
In [269]: frame
Out[269]: 
   a  b  c   d
0  1  0  2 NaN
1  4  3  5 NaN
2  7  6  8 NaN

# 参数为1轴,表示删除1轴上带有缺省值NaN的一列
# 若参数为0轴,删除所有值得到一个空的frame?
In [270]: frame.dropna(axis=1)
Out[270]: 
   a  b  c
0  1  0  2
1  4  3  5
2  7  6  8

# drop函数,默认参数是行索引,即index
In [275]: frame.drop(0)
Out[275]: 
   a  b  c   d
1  4  3  5 NaN
2  7  6  8 NaN

# 若删除列,请指定轴方向
n [277]: frame.drop('d', axis=1)
Out[277]: 
   a  b  c
0  1  0  2
1  4  3  5
2  7  6  8

1.3. 通过索引过滤


In [278]: frame
Out[278]: 
   a  b  c   d
0  1  0  2 NaN
1  4  3  5 NaN
2  7  6  8 NaN

# 获取b列小于4的行
In [280]: frame[frame['b'] < 4]
Out[280]: 
   a  b  c   d
0  1  0  2 NaN
1  4  3  5 NaN

# 获取b列小于4且c列小于3的行
# 这里‘&’代表and,‘|’代表or
In [281]: frame[(frame['b'] < 4) &  (frame['c'] < 3)]
Out[281]: 
   a  b  c   d
0  1  0  2 NaN

1.4. 通过索引排序


对行和列的索引进行排序使用sort_index函数,返回一个新的对象,若需要按值排序,Series使用order函数,DataFrame使用sort_values函数,排序的时候,缺省值默认是放到末尾的。

In [294]: frame = DataFrame(np.arange(8).reshape(2,4), index=[3, 1], columns=['d', 'b', 'a', 'c'])

In [295]: frame
Out[295]: 
   d  b  a  c
3  0  1  2  3
1  4  5  6  7

# 按照index升序排列
In [296]: frame.sort_index()
Out[296]: 
   d  b  a  c
1  4  5  6  7
3  0  1  2  3

# 按照column生序排列
In [297]: frame.sort_index(axis=1)
Out[297]: 
   a  b  c  d
3  2  1  3  0
1  6  5  7  4

# 同时按照行和列排序
In [299]: frame.sort_index(axis=1).sort_index()
Out[299]: 
   a  b  c  d
1  6  5  7  4
3  2  1  3  0
# 按值排序,需指定轴方向和基准列
In [311]: frame
Out[311]: 
   d  b  a  c
1  4  5  6  7
3  0  1  2  3

In [312]: frame.sort_values(by='c', axis=0)
Out[312]: 
   d  b  a  c
3  0  1  2  3
1  4  5  6  7

1.5 通过索引定位和切片


  • loc/iloc/ix方式

loc、iloc以及ix都是定位DataFrame行以及进行索引切片的重要方法

  1. Positional-oriented (Python slicing style : exclusive of end)
  2. Label-oriented (Non-Python slicing style : inclusive of end)
  3. General (Either slicing style : depends on if the slice contains labels or positions)

分别解释一下

  • iloc是基于位置的索引,参数只允许是RowID这样的整数,例如,选取第1-2行使用df.loc[1:3],注意第3行是不包含的(满足python style);

  • loc是基于标签的索引,也就是我们自定义的索引,同样选取第1-2行使用df.loc[1:2],注意它不满足python style;

  • ix是以上二者的综合,既可以使用RowID,又可以使用自定义索引,要视情况不同来使用,如果索引既有数字又有英文,那么这种方式是不建议使用的,很容易导致定位的混乱,可以想象,如果索引是A, B, C, D, 1, 2, 3,我们使用切片df.ix[:3]是否能得到我们想要的样子呢?

所以,建议大家养成习惯,活用loc和iloc即可,附带loc切片选取数据块的方法:

可以再研究下它们的效率,例如读取一个30k条记录的数据集,使用以下三种方式进行切片操作,效率相差不是很大,官方文档也未说明他们在效率上有何不同,以后可以使用更大的数据集来做实验,毕竟数据分析方面效率也是很重要的指标,选取的方法好了,工作效率也更高。

In [42]: %timeit df.ix[:10]
10000 loops, best of 3: 138 µs per loop

In [43]: %timeit df.loc[:10]
The slowest run took 4.89 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 140 µs per loop

In [44]: %timeit df.iloc[:11]
10000 loops, best of 3: 130 µs per loop

2. pandas统计


一次性对所有列产生汇总统计可以用describe函数,包括数量count(非NA),平均值 mean,最小值min,最大值max,分位数quantile(25%/50%/75%),标准差std等,当然也可以调用相应的方法单独求出,默认不加参数都是对列操作。

例如,对以下3×4的矩阵:

In [314]: frame = DataFrame(randn(3, 4))

In [315]: frame
Out[315]: 
          0         1         2         3
0  0.143605  0.543037  1.509424 -0.849529
1  1.516573 -1.037837 -0.323093 -0.380521
2 -0.488021 -1.007932 -0.751957  1.693078

In [316]: frame.describe()
Out[316]: 
              0         1         2         3
count  3.000000  3.000000  3.000000  3.000000
mean   0.390719 -0.500911  0.144791  0.154343
std    1.024889  0.904209  1.201103  1.353060
min   -0.488021 -1.037837 -0.751957 -0.849529
25%   -0.172208 -1.022885 -0.537525 -0.615025
50%    0.143605 -1.007932 -0.323093 -0.380521
75%    0.830089 -0.232447  0.593165  0.656278
max    1.516573  0.543037  1.509424  1.693078

In [317]: frame.max()
Out[317]: 
0    1.516573
1    0.543037
2    1.509424
3    1.693078
dtype: float64

In [318]: frame.count()
Out[318]: 
0    3
1    3
2    3
3    3
dtype: int64

In [319]: frame.sum()
Out[319]: 
0    1.172157
1   -1.502732
2    0.434374
3    0.463028
dtype: float64

相关系数和协方差的计算也很方便,使用corrcov函数即可

In [321]: frame = DataFrame({'col1':[1,3,4,3,4],'col2':[2,3,1,2,3],'col3':[1,5,2,4,4]})

In [322]: frame
Out[322]: 
   col1  col2  col3
0     1     2     1
1     3     3     5
2     4     1     2
3     3     2     4
4     4     3     4

# 列之间的相关系数
# 默认参数method='pearson',此外还有kendall,spearman
In [323]: frame.corr()
Out[323]: 
          col1      col2      col3
col1  1.000000  0.000000  0.496904
col2  0.000000  1.000000  0.691023
col3  0.496904  0.691023  1.000000

# 列之间的协方差
In [324]: frame.cov()
Out[324]: 
      col1  col2  col3
col1   1.5  0.00  1.00
col2   0.0  0.70  0.95
col3   1.0  0.95  2.70

# 也可以单指定某一列计算
In [331]: frame.corrwith(frame.col1)
Out[331]: 
col1    1.000000
col2    0.000000
col3    0.496904
dtype: float64

还有一个计算频率的方法value_counts,和apply函数结合使用,可以实现wordcount

In [336]: wordcounts = frame.apply(pd.value_counts).fillna(0)

# 左列是矩阵中的不同元素
In [337]: wordcounts
Out[337]: 
   col1  col2  col3
1   1.0   1.0   1.0
2   0.0   2.0   1.0
3   2.0   2.0   0.0
4   2.0   0.0   2.0
5   0.0   0.0   1.0
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容