dataframe包简介

dataframe包适合处理表格型数据,主要包括两种数据类型:Series和DataFrame。Series是一维带标签(index)的数组,index默认是从 0开始的整型数组,可以从list创建Series对象。

>>> s = Series([1,3,5,nan,6,8])
>>> s
0  1.0
1  3.0
2  5.0
3  NaN
4  6.0
5  8.0

DataFrame是二维带标签的数据结构,不同列可以是不同的数据类型。可以从dict数据创建DataFrame对象。

>>> df = DataFrame({'A' : 1.,
...     'C' : [1,2,3,4],
...     'D' : array([3] * 4),
...     'E' : ['test','train','test','train'],
...     'F' : 'foo'})
>>> df
     A C D     E   F
0  1.0 1 3  test foo
1  1.0 2 3 train foo
2  1.0 3 3  test foo
3  1.0 4 3 train foo

也可以从一个NDArray数组创建DataFrame对象,并定义index和columns(各列的名称)。date_range函数生成一个时间类型的index。

>>> dates = date_range('20130101', periods=6)
>>> dates
DateTimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'])
>>> df = DataFrame(random.randn(6,4), index=dates, columns=list('ABCD'))
>>> df
                   A         B         C         D
2013-01-01  0.235064 -0.419857 -0.888507 -3.056019
2013-01-02 -0.476107  1.831309 -0.800894  0.936860
2013-01-03  0.362006 -0.260680  0.991738 -0.156389
2013-01-04  0.628134 -0.357041 -1.476449  0.547806
2013-01-05  0.022919 -0.817809 -0.187390  0.074602
2013-01-06 -0.697131 -2.058141 -0.380428 -0.719107

DataFrame对象的head和tail方法可以显示数据的前5行和后5行,也可以增加一个参数指定显示多少行数据。

>>> df.head()
                   A         B         C         D
2013-01-01  0.730520  0.088258  0.488905  0.461837
2013-01-02  0.448598  0.697712  0.277767  0.759961
2013-01-03  0.219245  0.920414  0.886056  0.222002
2013-01-04  0.883879  0.439466  0.392876  0.994732
2013-01-05  0.881501  0.283149  0.247825  0.593564
...
>>> df.tail(3)
                   A         B         C         D
2013-01-04  0.883879  0.439466  0.392876  0.994732
2013-01-05  0.881501  0.283149  0.247825  0.593564
2013-01-06  0.511849  0.077208  0.040160  0.683068

DataFrame对象包含index、columns和values属性,分别是行标签、列标签和数据数组。

>>> df.index
DateTimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'])
>>> df.columns
Index(['A', 'B', 'C', 'D'])
>>> df.values
array([[0.730519863614471, 0.08825840967622589, 0.4889045498516358, 0.461837214623537]
      [0.4485983912283127, 0.6977123432245299, 0.2777673057578094, 0.7599608278137966]
      [0.21924450192488787, 0.9204140116502296, 0.886055787176944, 0.22200160212508913]
      [0.8838785592364334, 0.43946558709097283, 0.3928764411717487, 0.9947320023919717]
      [0.8815007984632135, 0.2831489393823492, 0.24782537013522343, 0.5935642792213479]
      [0.5118487849556497, 0.07720751395148084, 0.04016027357410157, 0.6830675875686567]])

describe方法可以显示数据的汇总情况,包括每列数据的个数、平均值、标准差、方差、最大值和最小值。

>>> df.describe()
              A         B         C         D
count  6.000000  6.000000  6.000000  6.000000
 mean  0.612598  0.417701  0.388932  0.619194
  std  0.265172  0.338873  0.286724  0.263857
  var  0.070316  0.114835  0.082211  0.069621
  max  0.883879  0.920414  0.886056  0.994732
  min  0.219245  0.077208  0.040160  0.222002

对DataFrame对象进行转置:

>>> df.T
  2013-01-01 2013-01-02 2013-01-03 2013-01-04 2013-01-05 2013-01-06
A   0.730520   0.448598   0.219245   0.883879   0.881501   0.511849
B   0.088258   0.697712   0.920414   0.439466   0.283149   0.077208
C   0.488905   0.277767   0.886056   0.392876   0.247825   0.040160
D   0.461837   0.759961   0.222002   0.994732   0.593564   0.683068

利用index进行排序:

>>> df.sort_index(ascending=False)
                   A         B         C         D
2013-01-06  0.511849  0.077208  0.040160  0.683068
2013-01-05  0.881501  0.283149  0.247825  0.593564
2013-01-04  0.883879  0.439466  0.392876  0.994732
2013-01-03  0.219245  0.920414  0.886056  0.222002
2013-01-02  0.448598  0.697712  0.277767  0.759961
2013-01-01  0.730520  0.088258  0.488905  0.461837

利用某一列的数值进行排序:

>>> df.sort_values(by='B')
                   A         B         C         D
2013-01-06  0.511849  0.077208  0.040160  0.683068
2013-01-01  0.730520  0.088258  0.488905  0.461837
2013-01-05  0.881501  0.283149  0.247825  0.593564
2013-01-04  0.883879  0.439466  0.392876  0.994732
2013-01-02  0.448598  0.697712  0.277767  0.759961
2013-01-03  0.219245  0.920414  0.886056  0.222002

从DataFrame对象中取出某一列的数据返回一个Series对象,包含DataFrame对象的index和该列的数据。

>>> df['A']
2013-01-01  0.730519863614471
2013-01-02  0.4485983912283127
2013-01-03  0.21924450192488787
2013-01-04  0.8838785592364334
2013-01-05  0.8815007984632135
2013-01-06  0.5118487849556497

DataFrame对象后方括号内可以是行的序号范围或index值的范围,可以从DataFrame对象中切片取出某些行返回一个新的DataFrame对象。

>>> df[0:3]
                   A         B         C         D
2013-01-01  0.730520  0.088258  0.488905  0.461837
2013-01-02  0.448598  0.697712  0.277767  0.759961
2013-01-03  0.219245  0.920414  0.886056  0.222002
>>> df['20130102':'20130104']
                   A         B         C         D
2013-01-02  0.448598  0.697712  0.277767  0.759961
2013-01-03  0.219245  0.920414  0.886056  0.222002
2013-01-04  0.883879  0.439466  0.392876  0.994732

也可以用loc接方括号从DataFrame对象中提取数据。

>>> df.loc[dates[0]]
                   A         B         C         D
2013-01-01  0.235064 -0.419857 -0.888507 -3.056019
>>> df.loc[:,['A','B']]
                   A         B
2013-01-01  0.730520  0.088258
2013-01-02  0.448598  0.697712
2013-01-03  0.219245  0.920414
2013-01-04  0.883879  0.439466
2013-01-05  0.881501  0.283149
2013-01-06  0.511849  0.077208
>>> df.loc['20130102':'20130104',['A','B']]
                   A         B
2013-01-02  0.448598  0.697712
2013-01-03  0.219245  0.920414
2013-01-04  0.883879  0.439466

用iloc或iat接方括号可以通过位置序号提取数据。在提取标量值时iat速度会更快。

>>> df.iloc[3]
A  0.8838785592364334
B  0.43946558709097283
C  0.3928764411717487
D  0.9947320023919717
>>> df.iloc[3:5,0:2]
                   A         B
2013-01-04  0.883879  0.439466
2013-01-05  0.881501  0.283149
>>> df.iloc[[1,2,4],[0,2]]
                   A         C
2013-01-02  0.448598  0.277767
2013-01-03  0.219245  0.886056
2013-01-05  0.881501  0.247825
>>> df.iloc[1,1]
0.6977123432245299
>>> df.iat[1,1]
0.6977123432245299

DataFrame对象的groupby方法可以用来对数据进行分组并返回GroupBy对象,GroupBy对象的count、sum、min、max、mean、median、 quantile、std等方法可以进行分类后的统计分析。

>>> df = DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
...                        'foo', 'bar', 'foo', 'foo'],
...                 'B' : ['one', 'one', 'two', 'three',
...                        'two', 'two', 'one', 'three'],
...                 'C' : random.randn(8),
...                 'D' : random.randn(8)})
>>> df
    A     B         C         D
0 foo   one  0.235064  0.235064
1 bar   one -0.419857 -0.419857
2 foo   two -0.888507 -0.888507
3 bar three -3.056019 -3.056019
4 foo   two -0.476107 -0.476107
5 bar   two  1.831309  1.831309
6 foo   one -0.800894 -0.800894
7 foo three  0.936860  0.936860
>>> df.groupby('A').sum()
             C          D
foo  -0.993584  -0.993584
bar  -1.644567  -1.644567
>>> df.groupby(['A','B']).sum()
             C         D
[foo, one] -0.565830 -0.565830
[bar, one] -0.419857 -0.419857
[foo, two] -1.364614 -1.364614
[bar, three] -3.056019 -3.056019
[bar, two]  1.831309  1.831309
[foo, three]  0.936860  0.936860

如果Series或DataFrame对象的index是时间数据类型,可以用resample方法对时间进行重采样,并对重采样后的GroupBy对象进行统计分析。 时间重采样可以看作特定的分组方式。下面的例子将秒分辨率数据重采样为5分钟分辨率数据。

>>> rng = date_range('1/1/2012', periods=100, freq='S')
>>> ts = Series(np.random.randint(0, 500, len(rng)), index=rng)
>>> ts.resample('5Min').sum()
2012-01-01 00:00  22561.0