pandas快速入门

pandas快速入门

numpy之后让我们紧接着学习pandas。Pandas最初被作为金融数据分析工具而开发出来,后来因为其强大性以及友好性,在数据分析领域被广泛使用,下面让我们一窥究竟。

本文参考官网给出的10 Minutes to pandas

对象创建

创建Series

#创建Series对象,index参数可省,默认为0~n-1的数字索引
#与numpy中的array一样,统一Series要求数据类型一致,这样可以加快处理速度
In [12]: s = pd.Series([1,2,3,np.nan,5,7],index=list('ABCDEF'))

In [13]: s
Out[13]:
A    1.0
B    2.0
C    3.0
D    NaN
E    5.0
F    7.0
dtype: float64

创建dataFrame

1.使用numpy array创建

In [4]: dates = pd.date_range('20170909',periods=6) #pandas对于时间的处理也很出色

In [5]: dates
Out[5]: 
DatetimeIndex(['2017-09-09', '2017-09-10', '2017-09-11', '2017-09-12',
               '2017-09-13', '2017-09-14'],
              dtype='datetime64[ns]', freq='D')

In [6]: df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=list('ABCD'))
   ...: #pd.DataFrame(数组, 行索引(可省), 列索引一般不省略)

In [7]: df
Out[7]: 
                   A         B         C         D
2017-09-09 -0.874363 -0.682658  0.533449 -0.396235
2017-09-10  0.878331  0.825946  1.075934 -0.820331
2017-09-11  0.720920  0.095851 -1.521827  1.252951
2017-09-12 -1.338117  0.787224  0.450896  0.586154
2017-09-13  0.954178 -0.475164  0.356891 -1.428600
2017-09-14  1.081780  0.846195 -0.070906 -0.805635

2.使用字典创建

df2 = pd.DataFrame({ 'A':[1,2,3],
                     'B':[3,4,5],
                     'C':np.arange(3)
        })
print df2

   A  B  C
0  1  3  0
1  2  4  1
2  3  5  2

网上使用多种数据类型也是可以的,博主认为同种类型更加常用一点吧

查看数据类型与numpy一样,是

df.dtypes

完成创建后,列将作为df的属性,可以通过df.A直接访问列

查看数据

查看数据就需要数据,博主这里使用的数据样例是之前爬取的中国城市历史天气

In [41]: df = pd.read_csv('./weather.csv')

In [42]: df.head(10) #这里取前10条记录,默认为5条
Out[42]: 
   city      pinYin  rainy  cloudy  sunny  overcast  snowy
0    阿城      acheng    563     761    809         8    215
1  昂昂溪区  angangxiqu    158     474    213        28     29
2   爱民区     aiminqu    269     304    253        17     72
3    安达        anda    523     977    700         0    169
4    安图        antu    580     868    704         2    219
5    鞍山      anshan    504     736    988         3    133
6   阿鲁旗       aluqi    445     821    935        54    120
7    敖汉       aohan    462     821    928        48    109
8   阿巴嘎       abaga    363     694   1086        54    169
9   阿荣旗     arongqi    522     942    624        74    212

...
In [47]: df.tail() #tail同理
Out[47]: 
     city      pinYin  rainy  cloudy  sunny  overcast  snowy
3200   资源      ziyuan   1230     824    199        95     23
3201   昭平    zhaoping   1333     845    131        61      0
3202   钟山  zhongshan1   1317     861    131        63      0
3203  昭平区  zhaopingqu    467     326     66        38      0
3204   彰化    zhanghua   1241     472     93       117      0

查看元数据

In [48]: df.index #行属性
Out[48]: RangeIndex(start=0, stop=3205, step=1)
  
In [49]: df.columns #列属性
Out[49]: 
Index([u'city', u'pinYin', u'rainy', u'cloudy', u'sunny', u'overcast',
       u'snowy'],
      dtype='object')

#统计数据,只会对数值类的进行计算
In [51]: df.describe()
Out[51]: 
             rainy       cloudy        sunny     overcast        snowy
count  3205.000000  3205.000000  3205.000000  3205.000000  3205.000000
mean    651.232137   797.288300   423.981591   104.118565    62.204680
std     344.324084   292.436344   302.132459    90.538331    81.090957
min       0.000000     0.000000     0.000000     0.000000     0.000000
25%     404.000000   596.000000   174.000000    43.000000     9.000000
50%     543.000000   855.000000   326.000000    86.000000    39.000000
75%     957.000000   991.000000   668.000000   136.000000    74.000000
max    1775.000000  1761.000000  1424.000000   614.000000   726.000000

另外,df.T求转置

排序

In [64]: df.sort_values(by='sunny',ascending=False).head()
Out[64]: 
      city        pinYin  rainy  cloudy  sunny  overcast  snowy
356     磴口       dengkou    221     675   1424         6     33
2418   乌后旗       wuhouqi    174     718   1421         8     29
790   杭锦后旗  hangjinhouqi    204     694   1421        11     28
508    额济纳         ejina     75     761   1405        30     17
2415    五原        wuyuan    234     675   1405         6     38

选择数据

基本操作(不推荐)

df['city'] #列选择,跟df.city一样
df[0:3] #行选择
  • 通过标签选择
In [74]: df.loc[0:5,['city','rainy']]
Out[74]: 
   city  rainy
0    阿城    563
1  昂昂溪区    158
2   爱民区    269
3    安达    523
4    安图    580
5    鞍山    504
#如果只选择一个标量,用at可以加速
In [79]: df.at[2,'snowy']
Out[79]: 72
  • 通过位置(整数)索引
#单行记录
In [80]: df.iloc[2]
Out[80]: 
city            爱民区
pinYin      aiminqu
rainy           269
cloudy          304
sunny           253
overcast         17
snowy            72
Name: 2, dtype: object
    
#中间切片
In [82]: df.iloc[3:6]
Out[82]: 
  city  pinYin  rainy  cloudy  sunny  overcast  snowy
3   安达    anda    523     977    700         0    169
4   安图    antu    580     868    704         2    219
5   鞍山  anshan    504     736    988         3    133

#取指定一个属性
In [83]: df.iloc[3:6,[2,4]]
Out[83]: 
   rainy  sunny
3    523    700
4    580    704
5    504    988
#同样,如果只选择一个标量,用at可以加速
In [84]: df.iloc[3,3]
Out[84]: 977

In [85]: df.iat[3,3]
Out[85]: 977
  • 布尔索引
In [92]: df[df.cloudy>1600]
Out[92]: 
     city       pinYin  rainy  cloudy  sunny  overcast  snowy
493    东方     dongfang    555    1761      3        58      0
841    哈密         hami    107    1752    467         0     44
2249   三亚        sanya    722    1621     16        18      0
2870   伊吾         yiwu    170    1627    466         1    110
2913  宜昌县  yichangxian    469    1667    121        80     19

#集合包含可以用isin来过滤
In [95]: df[df.snowy.isin([0,1,2,3,4,5])]

设置新值

1.通过Series添加新列

In [45]: s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20130102', periods=6))
In [47]: df['F'] = s1

2.直接修改数据项

In [48]: df.at[dates[0],'A'] = 0
In [49]: df.iat[0,1] = 0
In [50]: df.loc[:,'D'] = np.array([5] * len(df))

#更高阶技巧
In [52]: df2 = df.copy()
In [53]: df2[df2 > 0] = -df2

处理缺失值nan

In [58]: df1.dropna(how='any') #删除有确实的记录
In [59]: df1.fillna(value=n5) #用默认值填充
In [60]: pd.isnull(df1) #返回布尔矩阵,找出有nan的位置

相关操作

统计

In [61]: df.mean() #对每一列进行统计
Out[61]: 
A   -0.004474
B   -0.383981
C   -0.687758
D    5.000000
F    3.000000
dtype: float64

In [62]: df.mean(1) #横轴统计
Out[62]: 
2013-01-01    0.872735
2013-01-02    1.431621
2013-01-03    0.707731
2013-01-04    1.395042
2013-01-05    1.883656
2013-01-06    1.592306
Freq: D, dtype: float64

Apply定制函数

In [66]: df.apply(np.cumsum)
Out[66]: 
                   A         B         C   D     F
2013-01-01  0.000000  0.000000 -1.509059   5   NaN
2013-01-02  1.212112 -0.173215 -1.389850  10   1.0
2013-01-03  0.350263 -2.277784 -1.884779  15   3.0
2013-01-04  1.071818 -2.984555 -2.924354  20   6.0
2013-01-05  0.646846 -2.417535 -2.648122  25  10.0
2013-01-06 -0.026844 -2.303886 -4.126549  30  15.0

In [67]: df.apply(lambda x: x.max() - x.min())
Out[67]: 
A    2.073961
B    2.671590
C    1.785291
D    0.000000
F    4.000000
dtype: float64

直方图统计

In [102]: df.cloudy.value_counts() #对于Series进行计数统计

字符串操作

#字符串的操作权包含在 str里面,也是对于Series
In [104]: df.pinYin.str.upper()

合并

concat

In [106]: df
Out[106]: 
   0  1  2  3
0  3  1  3  8
1  9  8  5  1
2  1  8  5  2
3  9  6  8  3
4  7  2  6  8
5  5  8  1  2
6  7  3  9  1
7  1  1  9  4
8  3  5  9  5
9  9  2  9  1

In [107]: pieces = [df[:3],df[3:7],df[7:]]

In [108]: pieces
Out[108]: 
[   0  1  2  3
 0  3  1  3  8
 1  9  8  5  1
 2  1  8  5  2,    0  1  2  3
 3  9  6  8  3
 4  7  2  6  8
 5  5  8  1  2
 6  7  3  9  1,    0  1  2  3
 7  1  1  9  4
 8  3  5  9  5
 9  9  2  9  1]

In [109]: pd.concat(pieces,axis=1)
Out[109]: 
     0    1    2    3    0    1    2    3    0    1    2    3
0  3.0  1.0  3.0  8.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
1  9.0  8.0  5.0  1.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
2  1.0  8.0  5.0  2.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN
3  NaN  NaN  NaN  NaN  9.0  6.0  8.0  3.0  NaN  NaN  NaN  NaN
4  NaN  NaN  NaN  NaN  7.0  2.0  6.0  8.0  NaN  NaN  NaN  NaN
5  NaN  NaN  NaN  NaN  5.0  8.0  1.0  2.0  NaN  NaN  NaN  NaN
6  NaN  NaN  NaN  NaN  7.0  3.0  9.0  1.0  NaN  NaN  NaN  NaN
7  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  1.0  1.0  9.0  4.0
8  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  3.0  5.0  9.0  5.0
9  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  9.0  2.0  9.0  1.0

In [110]: pd.concat(pieces,axis=0)
Out[110]: 
   0  1  2  3
0  3  1  3  8
1  9  8  5  1
2  1  8  5  2
3  9  6  8  3
4  7  2  6  8
5  5  8  1  2
6  7  3  9  1
7  1  1  9  4
8  3  5  9  5
9  9  2  9  1

join

与SQL中的join一致,调用的是merge方法

#key出现重复,所以直接使用笛卡尔积
In [114]: left = pd.DataFrame({'key':['a','a'],'value':[1,2]})

In [115]: right = pd.DataFrame({'key':['a','a'],'value':[3,4]})

In [116]: pd.merge(left, right, on='key')
Out[116]: 
  key  value_x  value_y
0   a        1        3
1   a        1        4
2   a        2        3
3   a        2        4

#on的key是unique则去重进行join
In [117]: right = pd.DataFrame({'key':['a','b'],'value':[3,4]})

In [118]: left = pd.DataFrame({'key':['a','b'],'value':[1,2]})

In [120]: pd.merge(left,right,on='key')
Out[120]: 
  key  value_x  value_y
0   a        1        3
1   b        2        4

append

添加一条记录

In [87]: df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])

In [88]: df
Out[88]: 
          A         B         C         D
0  1.346061  1.511763  1.627081 -0.990582
1 -0.441652  1.211526  0.268520  0.024580
2 -1.577585  0.396823 -0.105381 -0.532532
3  1.453749  1.208843 -0.080952 -0.264610
4 -0.727965 -0.589346  0.339969 -0.693205
5 -0.339355  0.593616  0.884345  1.591431
6  0.141809  0.220390  0.435589  0.192451
7 -0.096701  0.803351  1.715071 -0.708758

In [89]: s = df.iloc[3]

In [90]: df.append(s, ignore_index=True)
Out[90]: 
          A         B         C         D
0  1.346061  1.511763  1.627081 -0.990582
1 -0.441652  1.211526  0.268520  0.024580
2 -1.577585  0.396823 -0.105381 -0.532532
3  1.453749  1.208843 -0.080952 -0.264610
4 -0.727965 -0.589346  0.339969 -0.693205
5 -0.339355  0.593616  0.884345  1.591431
6  0.141809  0.220390  0.435589  0.192451
7 -0.096701  0.803351  1.715071 -0.708758
8  1.453749  1.208843 -0.080952 -0.264610

#注意添加的记录数据类型是Series
In [124]: s
Out[124]: 
A    0.077384
B   -0.716115
C    0.427943
D    0.057282
Name: 3, dtype: float64

分组

In [91]: df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
   ....:                           'foo', 'bar', 'foo', 'foo'],
   ....:                    'B' : ['one', 'one', 'two', 'three',
   ....:                           'two', 'two', 'one', 'three'],
   ....:                    'C' : np.random.randn(8),
   ....:                    'D' : np.random.randn(8)})
   ....: 

In [92]: df
Out[92]: 
     A      B         C         D
0  foo    one -1.202872 -0.055224
1  bar    one -1.814470  2.395985
2  foo    two  1.018601  1.552825
3  bar  three -0.595447  0.166599
4  foo    two  1.395433  0.047609
5  bar    two -0.392670 -0.136473
6  foo    one  0.007207 -0.561757
7  foo  three  1.928123 -1.623033

In [93]: df.groupby('A').sum()
Out[93]: 
            C        D
A                     
bar -2.802588  2.42611
foo  3.146492 -0.63958
#也可以使用其他函数 如
#df.groupby('A').apply(np.sum)

作图

In [135]: ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))

In [136]: ts = ts.cumsum()

In [137]: ts.plot()
Out[137]: <matplotlib.axes._subplots.AxesSubplot at 0x1187d7278>
In [138]: plt.show()
#以Index为横坐标,其他值为纵坐标作图

小结

pandas还有很多高级用法,博主也在学习中,以上只列出比较常用的。

根据二八定理,差不多可以开始使用pandas愉快地处理数据了,其他的高级用法就即用即查吧,欢迎大家讨论交流。

posted @ 2017-09-09 22:54  潇雨危栏  阅读(466)  评论(0编辑  收藏  举报