博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python pandas 0.19.1 Intro to Data Structures 数据结构介绍 文档翻译
阅读量:5099 次
发布时间:2019-06-13

本文共 30623 字,大约阅读时间需要 102 分钟。

官方文档链接

数据结构介绍

我们将以一个快速的、非全面的pandas的基础数据结构概述来开始。应用在所有对象的数据类型、索引和轴标签/对齐等的基础操作。首先我们需要向你的命名空间引入numpy和pandas。

In [1]: import numpy as npIn [2]: import pandas as pd

有个宗旨需要牢记:数据对齐是内在的。标签和数据间的链接不会被轻易改变,除非你明确地做了相应的操作来让它改变。

我们将会对数据结构进行简要的介绍,然后会考虑到单独部分的功能和方法。

Series

 是一个一维的、可容纳任何数据类型(整型,字符串,浮点型数据,Python对象等)的标记数组。它的轴标签统称为索引。最基本的创建一个Series的方法是:

>>> s = pd.Series(data, index=index)

在这里,data可以是多种事物:

  • 一个Python字典
  • 一个多维数组
  • 一个标量值(如5)

传入的index是一个轴标签列表。因此,根据data的不同,有如下几种情况:

基于多维数组

如果data是一个多维数组,index必须和data的长度相同。如果没有传入index,系统将会自动创建一个index,其值为[0, ..., len(data) - 1].

In [3]: s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])In [4]: sOut[4]: a    0.2735b    0.6052c   -0.1692d    1.8298e    0.5432dtype: float64In [5]: s.indexOut[5]: Index([u'a', u'b', u'c', u'd', u'e'], dtype='object')In [6]: pd.Series(np.random.randn(5))Out[6]: 0    0.36741   -0.82302   -1.02953   -1.05234   -0.8502dtype: float64

注意

从v0.8.0版本开始,pandas开始支持非唯一索引值。如果尝试一个不支持重复索引值的操作,将会引发一个异常。懒惰的原因几乎都是源于性能(有许多计算中的实例,如GroupBy中的一部分就不需要用到index)

基于字典

如果data是一个字典,如果向index 中传入的值是data中的,那么index中对应于标签数据的值将会被移出。否则,如果可能的话,将会构成一个基于排序字典的index。

In [7]: d = {'a' : 0., 'b' : 1., 'c' : 2.}In [8]: pd.Series(d)Out[8]: a    0.0b    1.0c    2.0dtype: float64In [9]: pd.Series(d, index=['b', 'c', 'd', 'a'])Out[9]: b    1.0c    2.0d    NaNa    0.0dtype: float64

注意

NaN在pandas代表缺失值。

基于标量值

如果data是一个标量值,就必须传入一个index。因为这个标量值的数量取决于index的长度。

In [10]: pd.Series(5., index=['a', 'b', 'c', 'd', 'e'])Out[10]: a    5.0b    5.0c    5.0d    5.0e    5.0dtype: float64

多维数组型Series

Series 非常像一个多维数组,拥有着numpy的大部分功能。然而,切片操作也会对索引进行切片。

In [11]: s[0]Out[11]: 0.27348116325673794In [12]: s[:3]Out[12]: a    0.2735b    0.6052c   -0.1692dtype: float64In [13]: s[s > s.median()]Out[13]: b    0.6052d    1.8298dtype: float64In [14]: s[[4, 3, 1]]Out[14]: e    0.5432d    1.8298b    0.6052dtype: float64In [15]: np.exp(s)Out[15]: a    1.3145b    1.8317c    0.8443d    6.2327e    1.7215dtype: float64

我们将在一个单独的 介绍基于数组的索引。

字典型Series

一个Series就像一个固定大小的字典,你可以通过索引标签来获取和设置Series的值:

In [16]: s['a']Out[16]: 0.27348116325673794In [17]: s['e'] = 12.In [18]: sOut[18]: a     0.2735b     0.6052c    -0.1692d     1.8298e    12.0000dtype: float64In [19]: 'e' in sOut[19]: TrueIn [20]: 'f' in sOut[20]: False

如果一个标签不包含在其中,将会引发一个异常:

>>> s['f']KeyError: 'f'

使用get方法,缺失的标签将会返回None或者指定的缺省值:

In [21]: s.get('f')In [22]: s.get('f', np.nan)Out[22]: nan

参见属性访问部分 .

Series的量化操作和标签对齐

当进行数据分析时,通过Series的一个又一个值进行循环通常是没有必要的。Series能够使用大部分的numpy方法。

In [23]: s + sOut[23]: a     0.5470b     1.2104c    -0.3385d     3.6596e    24.0000dtype: float64In [24]: s * 2Out[24]: a     0.5470b     1.2104c    -0.3385d     3.6596e    24.0000dtype: float64In [25]: np.exp(s)Out[25]: a         1.3145b         1.8317c         0.8443d         6.2327e    162754.7914dtype: float64

Series和多维数组的关键区别在于Series的数据对齐是基于标签的。因此,不管你的Series是不是有相同的标签,你都可以无所顾忌地进行计算。

In [26]: s[1:] + s[:-1]Out[26]: a       NaNb    1.2104c   -0.3385d    3.6596e       NaNdtype: float64

在未对齐的Series进行操作将会涉及到索引的联合。如果一个标签在一个Series或其他中都不存在,在结果中将会被标记为缺失值。能够在未做任何明确的数据对齐的情况下编写代码,为交互式数据分析和研究提供了极大的自由和灵活性。

注意

一般来说,为了避免信息错乱,我们选择在不同的索引对象间的操作的默认结果产生索引的联合。

name属性

Series还有一个name属性:

In [27]: s = pd.Series(np.random.randn(5), name='something')In [28]: sOut[28]: 0    1.51401   -1.23452    0.56663   -1.01844    0.1081Name: something, dtype: float64In [29]: s.nameOut[29]: 'something'

Series的name属性在很多情况下会被自动分配,特别是在你在下面看到的dataframe的一维切片中。

0.18.0.的新版本。

你可以通过  方法来对Series重命名。

In [30]: s2 = s.rename("different")In [31]: s2.nameOut[31]: 'different'

注意s和s2是不同的对象。

DataFrame

DataFrame 是一个拥有不同类型的列的二维的标记数据结构。你可以把它想成一个电子表格或数据库表,或者一个Seires对象的字典。它是pandas对象中最常用的一种。和Series一样,dataframe能够接受不同类型的输入:

  • 一维数组,列表或Seires的字典
  • 二维的bumpy数组
  • 结构化或记录数组
  • 一个 Series
  • 另外一个DataFrame

对于dataframe中的data, 你可以选择传入index(行标签)和columns(列标签)。如果你传入了一个index和/或columns,你必须保证你传入的生成data frame的index和/或columns。因此,一个Series字典加上一个明确的索引将会丢弃所有不匹配索引的数据。

如果没有传入轴标签,系统将会基于常识规则根据输入的数据构造轴标签。

基于Series字典或字典的data frame

最终index是多种Series的index的联合。如果有任何嵌套字典,将会首先被转换成Series。如果没有传入列,列将会是字典的键的排序列表。

In [32]: d = {'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']),   ....:      'two' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}   ....: In [33]: df = pd.DataFrame(d)In [34]: dfOut[34]:    one  twoa  1.0  1.0b  2.0  2.0c  3.0  3.0d  NaN  4.0In [35]: pd.DataFrame(d, index=['d', 'b', 'a'])Out[35]:    one  twod  NaN  4.0b  2.0  2.0a  1.0  1.0In [36]: pd.DataFrame(d, index=['d', 'b', 'a'], columns=['two', 'three'])Out[36]:    two threed  4.0   NaNb  2.0   NaNa  1.0   NaN

行和列标签能够分别通过访问index和columns属性进行访问。

注意

 当一个特殊的列集合和字典同时被传入时,传入的列将会重写字典中的键。
In [37]: df.indexOut[37]: Index([u'a', u'b', u'c', u'd'], dtype='object')In [38]: df.columnsOut[38]: Index([u'one', u'two'], dtype='object')

基于多维数组/列表的字典的data frame

多维数组必须都是相同长度的,如果传入了一个index,它必须和数组的长度相同。如果没有传入index,那么自动生成的index就是range(n),其中n是数组的长度。

In [39]: d = {'one' : [1., 2., 3., 4.],   ....:      'two' : [4., 3., 2., 1.]}   ....: In [40]: pd.DataFrame(d)Out[40]:    one  two0  1.0  4.01  2.0  3.02  3.0  2.03  4.0  1.0In [41]: pd.DataFrame(d, index=['a', 'b', 'c', 'd'])Out[41]:    one  twoa  1.0  4.0b  2.0  3.0c  3.0  2.0d  4.0  1.0

基于结构化或记录数组的data frame

这种情况和数组字典的情况相同。

In [42]: data = np.zeros((2,), dtype=[('A', 'i4'),('B', 'f4'),('C', 'a10')])In [43]: data[:] = [(1,2.,'Hello'), (2,3.,"World")]In [44]: pd.DataFrame(data)Out[44]:    A    B      C0  1  2.0  Hello1  2  3.0  WorldIn [45]: pd.DataFrame(data, index=['first', 'second'])Out[45]:         A    B      Cfirst   1  2.0  Hellosecond  2  3.0  WorldIn [46]: pd.DataFrame(data, columns=['C', 'A', 'B'])Out[46]:        C  A    B0  Hello  1  2.01  World  2  3.0

注意

DataFrame 并不打算向二维bumpy数组那样.

基于字典列表的data frame

In [47]: data2 = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]In [48]: pd.DataFrame(data2)Out[48]:    a   b     c0  1   2   NaN1  5  10  20.0In [49]: pd.DataFrame(data2, index=['first', 'second'])Out[49]:         a   b     cfirst   1   2   NaNsecond  5  10  20.0In [50]: pd.DataFrame(data2, columns=['a', 'b'])Out[50]:    a   b0  1   21  5  10

基于集合字典的data frame

你可以通过传入一个集合字典来自动创建一个多索引的frame。

In [51]: pd.DataFrame({('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2},   ....:               ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4},   ....:               ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6},   ....:               ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8},   ....:               ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}})   ....: Out[51]:        a              b             a    b    c    a     bA B  4.0  1.0  5.0  8.0  10.0  C  3.0  2.0  6.0  7.0   NaN  D  NaN  NaN  NaN  NaN   9.0

基于一个Series

创建的结果是一个和输入的Series有着相同index的dataframe ,其中一列的名字是Series的原始名字(如果其他列的名字没有提供的话)

缺失数据

更多详见  部分。使用np.nan能够构造一个包含缺失值的data frame。或者,你还可以传入一个numpy.MaskedArray,它的mask项目将被视为缺失值。

交替的构造函数

DataFrame.from_dict

DataFrame.from_dict 接收一个字典或一个数组序列的字典,并返回一个data frame。 It operates like the DataFrame constructor except for the orient parameter which is 'columns' by default, but which can be set to 'index' in order to use the dict keys as row labels.

DataFrame.from_records

DataFrame.from_records 接收一个集合列表或结构化类型的多维数组。它与正常的dataframe构造器类似,不同的是它的index或许是一个特定的结构化类型。例如:

In [52]: dataOut[52]: array([(1, 2.0, 'Hello'), (2, 3.0, 'World')],       dtype=[('A', '

DataFrame.from_items

DataFrame.from_items的形式也与dataframe构造器类似,它接收一个(键,值)序列,其中键是列名(或行名,如果零orient=“index”的话),值是列值(或行值)。这对于构造一个特定顺序列dataframe来说非常有用。

In [54]: pd.DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])])Out[54]:    A  B0  1  41  2  52  3  6

如果你传入 orient='index’关键字,值就会变成行标签。但是这种情况下你必须接着传入列名:

In [55]: pd.DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])],   ....:                         orient='index', columns=['one', 'two', 'three'])   ....: Out[55]:    one  two  threeA    1    2      3B    4    5      6

列的选取,增加和删除

你可以使用一个相同indexed的Series对象的字典的语法对dataframe进行操作。获取,设置和删除列的语法和字典操作类似:

In [56]: df['one']Out[56]: a    1.0b    2.0c    3.0d    NaNName: one, dtype: float64In [57]: df['three'] = df['one'] * df['two']In [58]: df['flag'] = df['one'] > 2In [59]: dfOut[59]:    one  two  three   flaga  1.0  1.0    1.0  Falseb  2.0  2.0    4.0  Falsec  3.0  3.0    9.0   Trued  NaN  4.0    NaN  False

列可以向一个字典那样被删除或移除:

In [60]: del df['two']In [61]: three = df.pop('three')In [62]: dfOut[62]:    one   flaga  1.0  Falseb  2.0  Falsec  3.0   Trued  NaN  False

当想要插入一个标量值时,它会自动填充整列:

In [63]: df['foo'] = 'bar'In [64]: dfOut[64]:    one   flag  fooa  1.0  False  barb  2.0  False  barc  3.0   True  bard  NaN  False  bar

当插入一个与当前dataframe有着不同index的Series时,将会以dataframe的index为基准。

In [65]: df['one_trunc'] = df['one'][:2]In [66]: dfOut[66]:    one   flag  foo  one_trunca  1.0  False  bar        1.0b  2.0  False  bar        2.0c  3.0   True  bar        NaNd  NaN  False  bar        NaN

你可以插入原始多维数组,但是它们的长度必须和dataframe的index的长度相匹配。

默认情况下会在末尾插入列。inser功能允许在特定位置插入列:

In [67]: df.insert(1, 'bar', df['one'])In [68]: dfOut[68]:    one  bar   flag  foo  one_trunca  1.0  1.0  False  bar        1.0b  2.0  2.0  False  bar        2.0c  3.0  3.0   True  bar        NaNd  NaN  NaN  False  bar        NaN

在方法链中分配新列

受  动词的变异, DataFrame 有一个  方法能够允许你轻易地创建一个从现有列派生出的新列。

In [69]: iris = pd.read_csv('data/iris.data')In [70]: iris.head()Out[70]:    SepalLength  SepalWidth  PetalLength  PetalWidth         Name0          5.1         3.5          1.4         0.2  Iris-setosa1          4.9         3.0          1.4         0.2  Iris-setosa2          4.7         3.2          1.3         0.2  Iris-setosa3          4.6         3.1          1.5         0.2  Iris-setosa4          5.0         3.6          1.4         0.2  Iris-setosaIn [71]: (iris.assign(sepal_ratio = iris['SepalWidth'] / iris['SepalLength'])   ....:      .head())   ....: Out[71]:    SepalLength  SepalWidth  PetalLength  PetalWidth         Name  sepal_ratio0          5.1         3.5          1.4         0.2  Iris-setosa       0.68631          4.9         3.0          1.4         0.2  Iris-setosa       0.61222          4.7         3.2          1.3         0.2  Iris-setosa       0.68093          4.6         3.1          1.5         0.2  Iris-setosa       0.67394          5.0         3.6          1.4         0.2  Iris-setosa       0.7200

以上是插入一个预先计算好的值的例子。我们也可以传入一个单参数的函数.

In [72]: iris.assign(sepal_ratio = lambda x: (x['SepalWidth'] /   ....:                                      x['SepalLength'])).head()   ....: Out[72]:    SepalLength  SepalWidth  PetalLength  PetalWidth         Name  sepal_ratio0          5.1         3.5          1.4         0.2  Iris-setosa       0.68631          4.9         3.0          1.4         0.2  Iris-setosa       0.61222          4.7         3.2          1.3         0.2  Iris-setosa       0.68093          4.6         3.1          1.5         0.2  Iris-setosa       0.67394          5.0         3.6          1.4         0.2  Iris-setosa       0.7200

assign 总是 returns返回一个数据的副本,而不会改变原data frame. 

当你手边没有一个参考的dataframe时,相对于要插入的实际值来说,传入一个可变的值是非常有用的。在链式操作中使用assign是非常普遍的。例如,我们可以限制dataframe只选择那些长度大于5的SepalLength进行计算和作图:

In [73]: (iris.query('SepalLength > 5')   ....:      .assign(SepalRatio = lambda x: x.SepalWidth / x.SepalLength,   ....:              PetalRatio = lambda x: x.PetalWidth / x.PetalLength)   ....:      .plot(kind='scatter', x='SepalRatio', y='PetalRatio'))   ....: Out[73]: 

由于传入了一个函数,该函数是在被分配到的dataframe上进行计算,重要的是,这个dataframe是那些长度大于5的行的dataframe.首先进行过滤,然后进行计算。在这个例子中,我们没有可过滤的dataframe。

assign的函数签名是简单的**kwargs。键是新字段的列名,值是用来插入的值(例如一个Series或者numpy数组),或者一个单参数的函数。将会返回一个插入了新值的dataframe的副本。

警告

由于assign的函数签名是**kwargs,是个字典,那么在生成的dataframe中插入的新列的顺序不能够保证和你传入的顺序一样。一般是在dataframe的最后按字母顺序插入。

所有的表达式会被首先计算,然后被分配。所以你不能在同一个assign中使用正在分配的列。

In [74]: # 不要这样做        df.assign(C = lambda x: x['A'] + x['B'],                  D = lambda x: x['A'] + x['C'])In [2]: # 而是需要把它分给两个assign        (df.assign(C = lambda x: x['A'] + x['B'])           .assign(D = lambda x: x['A'] + x['C']))

索引/选取

基本的索引如下所示:

操作 语法 结果
选取列 df[col] Series
通过标签选取行 df.loc[label] Series
通过整数位置选取行 df.iloc[loc] Series
行切片 df[5:10] DataFrame
通过布尔向量选取行 df[bool_vec] DataFrame

选取行,例如,返回一个Series,其index就是dataframe的列。

In [75]: df.loc['b']Out[75]: one              2bar              2flag         Falsefoo            barone_trunc        2Name: b, dtype: objectIn [76]: df.iloc[2]Out[76]: one             3bar             3flag         Truefoo           barone_trunc     NaNName: c, dtype: object

对于更复杂的基于标签的索引和切片的更详尽的处理,参见 . 

数据对齐和算法

dataframe对象间的数据对齐会根据索引(行标签)和列自动对齐。同样,产生的结果将是行和列标签的联合。

In [77]: df = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D'])In [78]: df2 = pd.DataFrame(np.random.randn(7, 3), columns=['A', 'B', 'C'])In [79]: df + df2Out[79]:         A       B       C   D0  0.5222  0.3225 -0.7566 NaN1 -0.8441  0.2334  0.8818 NaN2 -2.2079 -0.1572 -0.3875 NaN3  2.8080 -1.0927  1.0432 NaN4 -1.7511 -2.0812  2.7477 NaN5 -3.2473 -1.0850  0.7898 NaN6 -1.7107  0.0661  0.1294 NaN7     NaN     NaN     NaN NaN8     NaN     NaN     NaN NaN9     NaN     NaN     NaN NaN

当在dataframe和Series间进行操作时,默认操作是将Series的index和dataframe的列对齐,并 行。例如:

In [80]: df - df.iloc[0]Out[80]:         A       B       C       D0  0.0000  0.0000  0.0000  0.00001 -2.6396 -1.0702  1.7214 -0.78962 -2.7662 -1.6918  2.2776 -2.54013  0.8679 -3.5247  1.9365 -0.13314 -1.9883 -3.2162  2.0464 -1.07005 -3.3932 -4.0976  1.6366 -2.16356 -1.3668 -1.9572  1.6523 -0.71917 -0.7949 -2.1663  0.9706 -2.62978 -0.8383 -1.3630  1.6702 -2.08659  0.8588  0.0814  3.7305 -1.3737

在对时间序列数据进行操作的特殊情况中,DataFrame 的index包含了日期,因此broadcasting将会对列进行:

In [81]: index = pd.date_range('1/1/2000', periods=8)In [82]: df = pd.DataFrame(np.random.randn(8, 3), index=index, columns=list('ABC'))In [83]: dfOut[83]:                  A       B       C2000-01-01  0.2731  0.3604 -1.15152000-01-02  1.1577  1.4787 -0.65282000-01-03 -0.7712  0.2203 -0.57392000-01-04 -0.6356 -1.1703 -0.07892000-01-05 -1.4687  0.1705 -1.87962000-01-06 -1.2037  0.9568 -1.13832000-01-07 -0.6540 -0.2169  0.38432000-01-08 -2.1639 -0.8145 -1.2475In [84]: type(df['A'])Out[84]: pandas.core.series.SeriesIn [85]: df - df['A']Out[85]:             2000-01-01 00:00:00  2000-01-02 00:00:00  2000-01-03 00:00:00  \2000-01-01                  NaN                  NaN                  NaN   2000-01-02                  NaN                  NaN                  NaN   2000-01-03                  NaN                  NaN                  NaN   2000-01-04                  NaN                  NaN                  NaN   2000-01-05                  NaN                  NaN                  NaN   2000-01-06                  NaN                  NaN                  NaN   2000-01-07                  NaN                  NaN                  NaN   2000-01-08                  NaN                  NaN                  NaN               2000-01-04 00:00:00 ...  2000-01-08 00:00:00   A   B   C  2000-01-01                  NaN ...                  NaN NaN NaN NaN  2000-01-02                  NaN ...                  NaN NaN NaN NaN  2000-01-03                  NaN ...                  NaN NaN NaN NaN  2000-01-04                  NaN ...                  NaN NaN NaN NaN  2000-01-05                  NaN ...                  NaN NaN NaN NaN  2000-01-06                  NaN ...                  NaN NaN NaN NaN  2000-01-07                  NaN ...                  NaN NaN NaN NaN  2000-01-08                  NaN ...                  NaN NaN NaN NaN  [8 rows x 11 columns]

警告

df - df['A']

现在已不再使用,并将会在以后的版本中移除。该操作正确的方法是:

df.sub(df['A'], axis=0)

对匹配和广播行为的显式控制,参见 .

你期待的对标量的操作:

In [86]: df * 5 + 2Out[86]:                  A       B       C2000-01-01  3.3655  3.8018 -3.75752000-01-02  7.7885  9.3936 -1.26412000-01-03 -1.8558  3.1017 -0.86962000-01-04 -1.1781 -3.8513  1.60562000-01-05 -5.3437  2.8523 -7.39822000-01-06 -4.0186  6.7842 -3.69152000-01-07 -1.2699  0.9157  3.92172000-01-08 -8.8194 -2.0724 -4.2375In [87]: 1 / dfOut[87]:                  A       B        C2000-01-01  3.6616  2.7751  -0.86842000-01-02  0.8638  0.6763  -1.53182000-01-03 -1.2967  4.5383  -1.74242000-01-04 -1.5733 -0.8545 -12.67592000-01-05 -0.6809  5.8662  -0.53202000-01-06 -0.8308  1.0451  -0.87852000-01-07 -1.5291 -4.6113   2.60192000-01-08 -0.4621 -1.2278  -0.8016In [88]: df ** 4Out[88]:                   A       B           C2000-01-01   0.0056  0.0169  1.7581e+002000-01-02   1.7964  4.7813  1.8162e-012000-01-03   0.3537  0.0024  1.0849e-012000-01-04   0.1632  1.8755  3.8733e-052000-01-05   4.6534  0.0008  1.2482e+012000-01-06   2.0995  0.8382  1.6789e+002000-01-07   0.1829  0.0022  2.1819e-022000-01-08  21.9244  0.4401  2.4219e+00

布尔操作也是如此:

In [89]: df1 = pd.DataFrame({'a' : [1, 0, 1], 'b' : [0, 1, 1] }, dtype=bool)In [90]: df2 = pd.DataFrame({'a' : [0, 1, 1], 'b' : [1, 1, 0] }, dtype=bool)In [91]: df1 & df2Out[91]:        a      b0  False  False1  False   True2   True  FalseIn [92]: df1 | df2Out[92]:       a     b0  True  True1  True  True2  True  TrueIn [93]: df1 ^ df2Out[93]:        a      b0   True   True1   True  False2  False   TrueIn [94]: -df1Out[94]:        a      b0  False   True1   True  False2  False  False

转置

转置可以通过T属性进行,和一个多维数组相似:

# 只显示前5行In [95]: df[:5].TOut[95]:    2000-01-01  2000-01-02  2000-01-03  2000-01-04  2000-01-05A      0.2731      1.1577     -0.7712     -0.6356     -1.4687B      0.3604      1.4787      0.2203     -1.1703      0.1705C     -1.1515     -0.6528     -0.5739     -0.0789     -1.8796

DataFrame与 NumPy功能的交互

如果dataframe中的数据是数值型的话,Numpy的功能(如log, exp, sort等)和多种其他的numpy功能可以没有问题地使用在dataframe上。

In [96]: np.exp(df)Out[96]:                  A       B       C2000-01-01  1.3140  1.4338  0.31622000-01-02  3.1826  4.3873  0.52062000-01-03  0.4625  1.2465  0.56332000-01-04  0.5296  0.3103  0.92412000-01-05  0.2302  1.1859  0.15262000-01-06  0.3001  2.6034  0.32042000-01-07  0.5200  0.8050  1.46862000-01-08  0.1149  0.4429  0.2872In [97]: np.asarray(df)Out[97]: array([[ 0.2731,  0.3604, -1.1515],       [ 1.1577,  1.4787, -0.6528],       [-0.7712,  0.2203, -0.5739],       [-0.6356, -1.1703, -0.0789],       [-1.4687,  0.1705, -1.8796],       [-1.2037,  0.9568, -1.1383],       [-0.654 , -0.2169,  0.3843],       [-2.1639, -0.8145, -1.2475]])

dataframe中的dot方法能够实现矩阵相乘。

In [98]: df.T.dot(df)Out[98]:          A       B       CA  11.1298  2.8864  6.0015B   2.8864  5.3895 -1.8913C   6.0015 -1.8913  8.6204

相似地,Series的dot方法能够执行点积:

In [99]: s1 = pd.Series(np.arange(5,10))In [100]: s1.dot(s1)Out[100]: 255

dataframe并不旨在做多维数组的替代,因为它的索引语法在矩阵方面和多维数组大不相同。

控制台显示

大规模的dataframe在控制台显示时将会被截断。你可以使用info()来获取一个概括。(下面我读取一个csv试图的baseball数据集)

In [101]: baseball = pd.read_csv('data/baseball.csv')In [102]: print(baseball)       id     player  year  stint  ...   hbp   sh   sf  gidp0   88641  womacto01  2006      2  ...   0.0  3.0  0.0   0.01   88643  schilcu01  2006      1  ...   0.0  0.0  0.0   0.0..    ...        ...   ...    ...  ...   ...  ...  ...   ...98  89533   aloumo01  2007      1  ...   2.0  0.0  3.0  13.099  89534  alomasa02  2007      1  ...   0.0  0.0  0.0   0.0[100 rows x 23 columns]In [103]: baseball.info()
RangeIndex: 100 entries, 0 to 99Data columns (total 23 columns):id 100 non-null int64player 100 non-null objectyear 100 non-null int64stint 100 non-null int64team 100 non-null objectlg 100 non-null objectg 100 non-null int64ab 100 non-null int64r 100 non-null int64h 100 non-null int64X2b 100 non-null int64X3b 100 non-null int64hr 100 non-null int64rbi 100 non-null float64sb 100 non-null float64cs 100 non-null float64bb 100 non-null int64so 100 non-null float64ibb 100 non-null float64hbp 100 non-null float64sh 100 non-null float64sf 100 non-null float64gidp 100 non-null float64dtypes: float64(9), int64(11), object(3)memory usage: 18.0+ KB

然而,使用to_string将会返回一个表格中的dataframe的字符串表示,虽然它不会总是符合控制台的宽度:

In [104]: print(baseball.iloc[-20:, :12].to_string())       id     player  year  stint team  lg    g   ab   r    h  X2b  X3b80  89474  finlest01  2007      1  COL  NL   43   94   9   17    3    081  89480  embreal01  2007      1  OAK  AL    4    0   0    0    0    082  89481  edmonji01  2007      1  SLN  NL  117  365  39   92   15    283  89482  easleda01  2007      1  NYN  NL   76  193  24   54    6    084  89489  delgaca01  2007      1  NYN  NL  139  538  71  139   30    085  89493  cormirh01  2007      1  CIN  NL    6    0   0    0    0    086  89494  coninje01  2007      2  NYN  NL   21   41   2    8    2    087  89495  coninje01  2007      1  CIN  NL   80  215  23   57   11    188  89497  clemero02  2007      1  NYA  AL    2    2   0    1    0    089  89498  claytro01  2007      2  BOS  AL    8    6   1    0    0    090  89499  claytro01  2007      1  TOR  AL   69  189  23   48   14    091  89501  cirilje01  2007      2  ARI  NL   28   40   6    8    4    092  89502  cirilje01  2007      1  MIN  AL   50  153  18   40    9    293  89521  bondsba01  2007      1  SFN  NL  126  340  75   94   14    094  89523  biggicr01  2007      1  HOU  NL  141  517  68  130   31    395  89525  benitar01  2007      2  FLO  NL   34    0   0    0    0    096  89526  benitar01  2007      1  SFN  NL   19    0   0    0    0    097  89530  ausmubr01  2007      1  HOU  NL  117  349  38   82   16    398  89533   aloumo01  2007      1  NYN  NL   87  328  51  112   19    199  89534  alomasa02  2007      1  NYN  NL    8   22   1    3    1    0

从0.10.0版本开始,列数过多的dataframes将默认多行显示:

In [105]: pd.DataFrame(np.random.randn(3, 12))Out[105]:          0         1         2         3         4         5         6   \0  2.173014  1.273573  0.888325  0.631774  0.206584 -1.745845 -0.505310   1 -1.240418  2.177280 -0.082206  0.827373 -0.700792  0.524540 -1.101396   2  0.269598 -0.453050 -1.821539 -0.126332 -0.153257  0.405483 -0.504557            7         8         9         10        11  0  1.376623  0.741168 -0.509153 -2.012112 -1.204418  1  1.115750  0.294139  0.286939  1.709761 -0.212596  2  1.405148  0.778061 -0.799024 -0.670727  0.086877

你可以通过设置display.width选项来改变每一行显示的列数量:

In [106]: pd.set_option('display.width', 40) # 默认为80In [107]: pd.DataFrame(np.random.randn(3, 12))Out[107]:          0         1         2   \0  1.179465  0.777427 -1.923460   1  0.054928  0.776156  0.372060   2 -0.243404 -1.506557 -1.977226            3         4         5   \0  0.782432  0.203446  0.250652   1  0.710963 -0.784859  0.168405   2 -0.226582 -0.777971  0.231309            6         7         8   \0 -2.349580 -0.540814 -0.748939   1  0.159230  0.866492  1.266025   2  1.394479  0.723474 -0.097256            9         10        11  0 -0.994345  1.478624 -0.341991  1  0.555240  0.731803  0.219383  2  0.375274 -0.314401 -2.363136

你可以通过设置display.max_colwidth来调整每一列的最大宽度:

In [108]: datafile={'filename': ['filename_01','filename_02'],   .....:           'path': ["media/user_name/storage/folder_01/filename_01",   .....:                    "media/user_name/storage/folder_02/filename_02"]}   .....: In [109]: pd.set_option('display.max_colwidth',30)In [110]: pd.DataFrame(datafile)Out[110]:       filename  \0  filename_01   1  filename_02                               path  0  media/user_name/storage/fo...  1  media/user_name/storage/fo...  In [111]: pd.set_option('display.max_colwidth',100)In [112]: pd.DataFrame(datafile)Out[112]:       filename  \0  filename_01   1  filename_02                                               path  0  media/user_name/storage/folder_01/filename_01  1  media/user_name/storage/folder_02/filename_02

你也可以通过expand_frame_repr 选项来禁用此功能。这将会在一个块中打印表格。

DataFrame 的列属性获取和IPython实现

如果一个dataframe列标签是一个有效的Python变量名,该列就能够通过属性的方式访问:

In [113]: df = pd.DataFrame({'foo1' : np.random.randn(5),   .....:                    'foo2' : np.random.randn(5)})   .....: In [114]: dfOut[114]:        foo1      foo20 -0.412237  0.2132321 -0.237644  1.7401392  1.272869 -0.2414913  1.220450 -0.8685144  1.315172  0.407544In [115]: df.foo1Out[115]: 0   -0.4122371   -0.2376442    1.2728693    1.2204504    1.315172Name: foo1, dtype: float64

列还与  实现机制相连,所以它们能够通过tab键实现自动完成。

In [5]: df.fo
df.foo1 df.foo2

Panel

Panel是一个用处不多但仍旧很重要的三维数据容器。词条 来自于计量经济学,并且是pandas这个名称的一部分来源( pan(el)-da(ta)-s)。panel的3个轴的名称旨在为包含panel数据的描述操作提供一些语义,尤其是panel数据的计量分析。然而,为了交叉分析dataframe对象集,你可能会发现panel的轴名称有点武断:

  • : 0轴,每一项对应于一个包含于其中的dataframe
  • 主轴: 1轴, 是每个data frame的index (行) 
  • 次轴: 2轴,是每个data frame的columns

Panels的构成也正如你想象的那样: 

基于可选轴标签的三维数组

In [116]: wp = pd.Panel(np.random.randn(2, 5, 4), items=['Item1', 'Item2'],   .....:               major_axis=pd.date_range('1/1/2000', periods=5),   .....:               minor_axis=['A', 'B', 'C', 'D'])   .....: In [117]: wpOut[117]: 
Dimensions: 2 (items) x 5 (major_axis) x 4 (minor_axis)Items axis: Item1 to Item2Major_axis axis: 2000-01-01 00:00:00 to 2000-01-05 00:00:00Minor_axis axis: A to D

基于dataframe对象字典的panel

In [118]: data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)),   .....:         'Item2' : pd.DataFrame(np.random.randn(4, 2))}   .....: In [119]: pd.Panel(data)Out[119]: 
Dimensions: 2 (items) x 4 (major_axis) x 3 (minor_axis)Items axis: Item1 to Item2Major_axis axis: 0 to 3Minor_axis axis: 0 to 2

注意,字典中的值只需要可转换为dataframe。因此,它们可以是dataframe中任何有效的输入。

一个有用的工厂方法是Panel.from_dict, 它能够接受一个dataframe字典和下列命名参数:

参数 默认 描述
intersect False 删除指数不对齐的元素
orient items 使dataframe的列作为panel的项 

例如,与上面的结构相比:

In [120]: pd.Panel.from_dict(data, orient='minor')Out[120]: 
Dimensions: 3 (items) x 4 (major_axis) x 2 (minor_axis)Items axis: 0 to 2Major_axis axis: 0 to 3Minor_axis axis: Item1 to Item2

Orient 对于混合类型的dataframe特别有用。如果你传入了一个其列是混合类型dataframe对象,除非你传入orient=‘minor’,否则所有的数据类型都将会向上变为object类型。

In [121]: df = pd.DataFrame({'a': ['foo', 'bar', 'baz'],   .....:                    'b': np.random.randn(3)})   .....: In [122]: dfOut[122]:      a         b0  foo -1.1428631  bar -1.0153212  baz  0.683625In [123]: data = {'item1': df, 'item2': df}In [124]: panel = pd.Panel.from_dict(data, orient='minor')In [125]: panel['a']Out[125]:   item1 item20   foo   foo1   bar   bar2   baz   bazIn [126]: panel['b']Out[126]:       item1     item20 -1.142863 -1.1428631 -1.015321 -1.0153212  0.683625  0.683625In [127]: panel['b'].dtypesOut[127]: item1    float64item2    float64dtype: object

注意

Panel由于不如Series和DataFrame常用,所以它也不像它们那样拥有那么多的好用的功能。dataframe中许多方法和选项在panel中都不能适用。我们将会继续努力。

基于使用to_panel方法的dataframe的panel

在v0.7中介绍了用来代替LongPanel的这个方法,它能够将一个两层索引的DataFrame转换为一个panel。

 

In [128]: midx = pd.MultiIndex(levels=[['one', 'two'], ['x','y']], labels=[[1,1,0,0],[1,0,1,0]])In [129]: df = pd.DataFrame({'A' : [1, 2, 3, 4], 'B': [5, 6, 7, 8]}, index=midx)In [130]: df.to_panel()Out[130]: 
Dimensions: 2 (items) x 2 (major_axis) x 2 (minor_axis)Items axis: A to BMajor_axis axis: one to twoMinor_axis axis: x to y

项的选取/增加/删除

和dataframe是多个Series组成的字典结构类似,panel就像是一个由多个dataframe组成的字典:

In [131]: wp['Item1']Out[131]:                    A         B         C         D2000-01-01 -0.729430  0.427693 -0.121325 -0.7364182000-01-02  0.739037 -0.648805 -0.383057  0.3850272000-01-03  2.321064 -1.290881  0.105458 -1.0970352000-01-04  0.158759 -1.261191 -0.081710  1.3905062000-01-05 -1.962031 -0.505580  0.021253 -0.317071In [132]: wp['Item3'] = wp['Item1'] / wp['Item2']

Panel的插入和删除的接口和dataframe一样。对于dataframe来说,如果项是一个有效的Python识别器,你可以适用Tab自动完成来像访问属性一样访问它。

转置

可以适用转置方法改变一个panel(该方法默认不是生成一个副本,除非数据是异构的)

In [133]: wp.transpose(2, 0, 1)Out[133]: 
Dimensions: 4 (items) x 3 (major_axis) x 5 (minor_axis)Items axis: A to DMajor_axis axis: Item1 to Item3Minor_axis axis: 2000-01-01 00:00:00 to 2000-01-05 00:00:00

索引/选取

操作 语法 结果
选取项 wp[item] DataFrame
在主轴标签上切片 wp.major_xs(val) DataFrame
在次轴标签上切片 wp.minor_xs(val) DataFrame

例如,使用之前的示例数据,我们可以:

In [134]: wp['Item1']Out[134]:                    A         B         C         D2000-01-01 -0.729430  0.427693 -0.121325 -0.7364182000-01-02  0.739037 -0.648805 -0.383057  0.3850272000-01-03  2.321064 -1.290881  0.105458 -1.0970352000-01-04  0.158759 -1.261191 -0.081710  1.3905062000-01-05 -1.962031 -0.505580  0.021253 -0.317071In [135]: wp.major_xs(wp.major_axis[2])Out[135]:       Item1     Item2     Item3A  2.321064 -0.538606 -4.309389B -1.290881  0.791512 -1.630905C  0.105458 -0.020302 -5.194337D -1.097035  0.184430 -5.948253In [136]: wp.minor_axisOut[136]: Index([u'A', u'B', u'C', u'D'], dtype='object')In [137]: wp.minor_xs('C')Out[137]:                Item1     Item2     Item32000-01-01 -0.121325  1.413524 -0.0858322000-01-02 -0.383057  1.243178 -0.3081272000-01-03  0.105458 -0.020302 -5.1943372000-01-04 -0.081710 -1.811565  0.0451052000-01-05  0.021253 -1.040542 -0.020425

Squeeze

改变一个对象维度的另一个方法是squeeze一个1-len对象,类似于wp['Item1]

In [138]: wp.reindex(items=['Item1']).squeeze()Out[138]:                    A         B         C         D2000-01-01 -0.729430  0.427693 -0.121325 -0.7364182000-01-02  0.739037 -0.648805 -0.383057  0.3850272000-01-03  2.321064 -1.290881  0.105458 -1.0970352000-01-04  0.158759 -1.261191 -0.081710  1.3905062000-01-05 -1.962031 -0.505580  0.021253 -0.317071In [139]: wp.reindex(items=['Item1'], minor=['B']).squeeze()Out[139]: 2000-01-01    0.4276932000-01-02   -0.6488052000-01-03   -1.2908812000-01-04   -1.2611912000-01-05   -0.505580Freq: D, Name: B, dtype: float64

转换为DataFrame

一个panel能够被一个分层索引的dataframe二维表格替代。详见。使用to_frame方法将一个panel转换为一个dataframe。

In [140]: panel = pd.Panel(np.random.randn(3, 5, 4), items=['one', 'two', 'three'],   .....:                  major_axis=pd.date_range('1/1/2000', periods=5),   .....:                  minor_axis=['a', 'b', 'c', 'd'])   .....: In [141]: panel.to_frame()Out[141]:                        one       two     threemajor      minor                              2000-01-01 a     -1.876826 -0.383171 -0.117339           b     -1.873827 -0.172217  0.780048           c     -0.251457 -1.674685  2.162047           d      0.027599  0.762474  0.8742332000-01-02 a      1.235291  0.481666 -0.764147           b      0.850574  1.217546 -0.484495           c     -1.140302  0.577103  0.298570           d      2.149143 -0.076021  0.8251362000-01-03 a      0.504452  0.720235 -0.388020           b      0.678026  0.202660 -0.339279           c     -0.628443 -0.314950  0.141164           d      1.191156 -0.410852  0.5659302000-01-04 a     -1.145363  0.542758 -1.749969           b     -0.523153  1.955407 -1.402941           c     -1.299878 -0.940645  0.623222           d     -0.110240  0.076257  0.0201292000-01-05 a     -0.333712 -0.897159 -2.858463           b      0.416876 -1.265679  0.885765           c     -0.436400 -0.528311  0.158014           d      0.999768 -0.660014 -1.981797

四维Panel 和多维Panel (不推荐使用)

警告

在0.19.0版本中不推荐使用四维Panel和多维panel,它们将会在以后的版本中被逐渐移除。推荐的使用方式是使用 来代替这种多维数据。Pandas提供了一个方法来自动完成此转换。

详见  。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

转载于:https://www.cnblogs.com/shuhanrainbow/p/6274000.html

你可能感兴趣的文章
Thrift Expected protocol id ffffff82 but got 0
查看>>
【2.2】创建博客文章模型
查看>>
Kotlin动态图
查看>>
从零开始系列之vue全家桶(1)安装前期准备nodejs+cnpm+webpack+vue-cli+vue-router
查看>>
Jsp抓取页面内容
查看>>
大三上学期软件工程作业之点餐系统(网页版)的一些心得
查看>>
可选参数的函数还可以这样设计!
查看>>
[你必须知道的.NET]第二十一回:认识全面的null
查看>>
Java语言概述
查看>>
关于BOM知识的整理
查看>>
使用word发布博客
查看>>
面向对象的小demo
查看>>
微服务之初了解(一)
查看>>
GDOI DAY1游记
查看>>
收集WebDriver的执行命令和参数信息
查看>>
数据结构与算法(三)-线性表之静态链表
查看>>
mac下的mysql报错:ERROR 1045(28000)和ERROR 2002 (HY000)的解决办法
查看>>
Hmailserver搭建邮件服务器
查看>>
django之多表查询-2
查看>>
快速幂
查看>>