pandas:强力的Python数据分析工具包

日期:2019年2月3日

版本:0.24.1

实用链接二进制安装 | 源代码仓库 | 问题和想法 | Q&A支持 | 邮件列表

pandas 是一个具有使用简单数据结构的开源高性能 Python 数据分析库。

了解关于库的更多细节:

开始

软件包概述

pandas 提供被设计用来使“关系型的”或“有标签的”数据的处理过程简明直观的一种快速、灵活、具有表现力的数据结构。 它的目标是成为Python的 真实世界 数据的数据处理过程基本的高级组件。 额外地,它还有一个更宽泛的目标是成为 面向所有语言的最强力、最灵活的开源数据处理/操作工具 ,并已经成功地朝着这个目标发展。

pandas非常适合许多种类型的数据:

  • 具有相异类型的表格数据,例如SQL数据库表以及Excel电子表格
  • 有序或无序的(可能不具有固定频率的)时间序列数据
  • 具有行列标签的任意矩阵(相同或相异类型)数据
  • 任何其他形式的观测/统计数据集。这类数据事实上完全不需要被标签标记就可以放入一个pandas数据结构中。

pandas有两种主要的数据结构, Series (一维)以及 DataFrame (二维), 能够处理绝大多数金融、统计、社会科学以及工程上许多领域的典型案例。 针对R语言的用户, DataFrame 提供了R的 data.DataFrame 能够提供的以及更多其他功能。 pandas构建在 NumPy 之上, 致力于很好地在科学计算的环境下整合许多其他第三方库。

pandas能在以下工作中取得良好的效果:
  • 简便地处理不论是否浮点数的 缺失数据 (被表示为NaN)
  • 大小可变性:从DataFrame以及更高维度对象中可以 增加或删除 列数据
  • 自动或显性的 数据对齐 :数据可以显性地对齐到一系列标签上,或者用户也可以忽略标签本身来让 SeriesDataFrame 等来为您在运算过程中自动对齐
  • 强大、灵活地对数据集执行分割、应用、组合操作,以便更好地聚合与转换数据
  • 使在其他Python和NumPy数据结构中零碎的、具有不同索引的数据 简便地转换 到DataFrame对象中
  • 智能基于标签的对大数据集 切片Fancy索引 以及 子集 操作
  • 直观地 合并连接 数据集
  • 灵活地 变形旋转 数据集
  • 对轴 按层级 标签(可能每次标记多个标签)
  • 供从平面文件(CSV与被符号分割的文件)、Excel电子表格、数据库与从超快速 HDF5格式 读写 中加载数据的稳定IO工具
  • 时间序列 相关功能: 按日期范围生成、频率转换、滑动窗口线性回归、日期的变动与延后等

上述许多准则都强调了在使用其他语言时与具体研究环境中出现的不足。 对数据科学家们,处理数据通常被分为几个阶段: 整理与清理数据、分析并建模,之后组织结果绘制适合的图表或表格来展示。 pandas是所有这些任务的理想工具。

一些其他说明

  • pandas很 。许多低级算法位在 Cython 代码中被广泛地进行了调整。 然而,在与其他任何泛化协调时通常会牺牲性能。 所以当您在您的应用中关注于某一种特性时您可能需要构建更快的针对具体需求的工具。
  • pandas是 statsmodels 的依赖库,这使得它成为了Python统计计算生态系统中的重要组成部分。
  • pandas在金融应用的产品中得到了广泛的应用。

数据结构

维数 名称 描述
一维 Series 一维同类型带有标签的数组
二维 DataFrame 通用的二维可能列类型相异可变大小的表数据结构

为什么不止一种数据结构?

关于pandas数据结构,最好的思维方式是把它看作针对低维数据的灵活的容器。 举个例子,DataFrame是Series的一种容器,而Series是标量的一种容器。 我们倾向于用一种类似于字典的风格来在这些容器中插入或移除对象。

并且我们倾向于使公共API函数具有合理的默认行为能确保考虑到时间序列和横切面数据集的典型位置。 当使用ndarray储存二维或三维数据时,用户在编写函数过程中需要考虑数据集的位置是一种负担; 轴或多或少被认为是相同的(C或Fortan中会影响性能优化的情况除外)。 在pandas中,轴被赋予了针对数据的更具语义化的意义; 即在某个具体的数据集中我们利用可能更“正确”的方式来定位数据。 这样做的目标是能够减少对用户在数据转换的下游函数编写过程中带来的情绪影响。

举个例子,对于表格数据(DataFrame)能在语义上相对轴1与轴2对考虑 索引 (行)与 更具有帮助。 在DataFrame中按列迭代可以带来更加可读的代码:

for col in df.columns:
    series = df[col]
    # 使用series做一些事

数据的可变性与复制

所有pandas数据结构都是值可变的(它们容纳的数值可以被修改)但不总是大小可变的。 Series的长度是不能被修改的,但是举例来说,DataFrame中可以插入新列。 然而大多数方法都产生新的对象而保持输入的数据不被修改。 总之在合理的时候我们 更倾向于不可变性

获得支持

向pandas提出问题或想法的第一站是 Github Issue Tracker 。 如果您有一个通用的问题,pandas社区的专家可以在 Stack Overflow 上回答您。

社区

pandas现在受到社区中全世界乐于贡献他们宝贵的时间与能量的爱好者们活跃的支持。 感谢我们 所有的贡献者

如果您也感兴趣做出贡献,请访问 贡献指南

pandas是受 NumFOCUS 赞助的项目。

如果您愿意帮助确保pandas的成功开发,使之成为世界级的开源项目,请向项目 捐赠

项目治理

pandas项目的非正式治理流程已经在2008年在 项目治理文档 中正式确立。 文档声明了我们如何制定决策以及如何协调社区的各种元素,包括开源协作开发与营利性实体或非营利性实体资金支持的关系。

Wes McKinney是终生仁慈独裁者(BDFL)

开发团队

核心团队成员以及更加详细的信息详见治理仓库的 人员页面

机构伙伴

目前机构合作伙伴的信息详见 pandas官方网站

协议

pandas项目协议:

BSD 3-Clause License

Copyright (c) 2008-2012, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

中文文档项目协议:

BSD 3-Clause License

Copyright (c) 2019, Chen Runze, Li Pengyu, Liu Haobo
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

10分钟了解pandas

这是一篇主要面向于新用户的关于pandas的简短介绍。 你可以在 Cookbook 中看到更为复杂的指导。

通常地,我们用下面这种方式导入库:

In [1]: import numpy as np

In [2]: import pandas as pd

创建对象

详见 数据结构介绍

用传一列表值的方式创建一个 Series ,使pandas构建一个默认的整数索引。

In [3]: s = pd.Series([1, 3, 5, np.nan, 6, 8])

In [4]: s
Out[4]: 
0    1.0
1    3.0
2    5.0
3    NaN
4    6.0
5    8.0
dtype: float64

用传NumPy数组的方式构建一个具有列标签与日期时间索引的 DataFrame

In [5]: dates = pd.date_range('20130101', periods=6)

In [6]: dates
Out[6]: 
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
               '2013-01-05', '2013-01-06'],
              dtype='datetime64[ns]', freq='D')

In [7]: df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))

In [8]: df
Out[8]: 
                   A         B         C         D
2013-01-01  0.409000  0.056469  0.241739 -0.287532
2013-01-02  1.302200 -1.029321  0.061776  2.394551
2013-01-03 -0.479307 -0.874806  1.642294  0.084300
2013-01-04  0.362947  0.639590 -0.235057  0.168113
2013-01-05  0.073892 -0.658483  0.184030  1.286847
2013-01-06  0.798556 -0.295086 -1.334530 -2.150138

用传可以被转换为序列的对象的列表的方式来构建 DataFrame

In [9]: df2 = pd.DataFrame({'A': 1.,
   ...:                     'B': pd.Timestamp('20130102'),
   ...:                     'C': pd.Series(1, index=list(range(4)), dtype='float32'),
   ...:                     'D': np.array([3] * 4, dtype='int32'),
   ...:                     'E': pd.Categorical(["test", "train", "test", "train"]),
   ...:                     'F': 'foo'})
   ...: 

In [10]: df2
Out[10]: 
     A          B    C  D      E    F
0  1.0 2013-01-02  1.0  3   test  foo
1  1.0 2013-01-02  1.0  3  train  foo
2  1.0 2013-01-02  1.0  3   test  foo
3  1.0 2013-01-02  1.0  3  train  foo

得到的 DataFrame 的每一列具有不同的 dtypes

In [11]: df2.dtypes
Out[11]: 
A           float64
B    datetime64[ns]
C           float32
D             int32
E          category
F            object
dtype: object

当你在使用IPython时列名(也是对象的公有属性)的自动补全会被自动打开:

In [12]: df2.<TAB>  # noqa: E225, E999
df2.A                  df2.bool
df2.abs                df2.boxplot
df2.add                df2.C
df2.add_prefix         df2.clip
df2.add_suffix         df2.clip_lower
df2.align              df2.clip_upper
df2.all                df2.columns
df2.any                df2.combine
df2.append             df2.combine_first
df2.apply              df2.compound
df2.applymap           df2.consolidate
df2.D

如您所见,ABCD 都被收进了自动补全。 而 E 也同样在其中,简短起见我们把其他的属性截去了。

查看数据

详见 基础

这里展示如何查看一个数据框最顶端和最底端的几行数据:

In [13]: df.head()
Out[13]: 
                   A         B         C         D
2013-01-01  0.409000  0.056469  0.241739 -0.287532
2013-01-02  1.302200 -1.029321  0.061776  2.394551
2013-01-03 -0.479307 -0.874806  1.642294  0.084300
2013-01-04  0.362947  0.639590 -0.235057  0.168113
2013-01-05  0.073892 -0.658483  0.184030  1.286847

In [14]: df.tail(3)
Out[14]: 
                   A         B         C         D
2013-01-04  0.362947  0.639590 -0.235057  0.168113
2013-01-05  0.073892 -0.658483  0.184030  1.286847
2013-01-06  0.798556 -0.295086 -1.334530 -2.150138

展示索引与列:

In [15]: df.index
Out[15]: 
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
               '2013-01-05', '2013-01-06'],
              dtype='datetime64[ns]', freq='D')

In [16]: df.columns
Out[16]: Index(['A', 'B', 'C', 'D'], dtype='object')

DataFrame.to_numpy() 提供了内含数据的NumPy表示。 由于pandas和NumPy的基本区别: 每一个NumPy数组内部只具有一个针对整个数组的dtype,而pandas的DataFrame每一列只有一种dtype 。 当你调用 DataFrame.to_numpy() 时,pandas将会识别出一种NumPy的dtype来适应DataFrame中所有列。 这很有可能是 object 类型,即把所有值都转换为Python的object类型。

对于 df,一个所有值都是浮点值的 DataFrameDataFrame.to_numpy() 很快并且不需要复制数据。

In [17]: df.to_numpy()
Out[17]: 
array([[ 0.40899992,  0.05646855,  0.2417389 , -0.28753204],
       [ 1.30219988, -1.02932145,  0.06177586,  2.39455137],
       [-0.47930678, -0.87480576,  1.64229368,  0.0842999 ],
       [ 0.36294748,  0.63959037, -0.23505711,  0.16811296],
       [ 0.07389217, -0.65848324,  0.18402954,  1.28684712],
       [ 0.79855606, -0.29508642, -1.33452979, -2.15013822]])

对于 df2,一个具有多种dtype的 DataFrame,相应地 DataFrame.to_numpy() 就具有昂贵的性能开销。

In [18]: df2.to_numpy()
Out[18]: 
array([[1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'test', 'foo'],
       [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'train', 'foo'],
       [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'test', 'foo'],
       [1.0, Timestamp('2013-01-02 00:00:00'), 1.0, 3, 'train', 'foo']],
      dtype=object)

注解

DataFrame.to_numpy() 在输出中 包括索引或列标签。

describe() 显示了数据的快速统计摘要:

In [19]: df.describe()
Out[19]: 
              A         B         C         D
count  6.000000  6.000000  6.000000  6.000000
mean   0.411215 -0.360273  0.093375  0.249357
std    0.608775  0.629118  0.956782  1.533487
min   -0.479307 -1.029321 -1.334530 -2.150138
25%    0.146156 -0.820725 -0.160849 -0.194574
50%    0.385974 -0.476785  0.122903  0.126206
75%    0.701167 -0.031420  0.227312  1.007164
max    1.302200  0.639590  1.642294  2.394551

转置你的数据:

In [20]: df.T
Out[20]: 
   2013-01-01  2013-01-02  2013-01-03  2013-01-04  2013-01-05  2013-01-06
A    0.409000    1.302200   -0.479307    0.362947    0.073892    0.798556
B    0.056469   -1.029321   -0.874806    0.639590   -0.658483   -0.295086
C    0.241739    0.061776    1.642294   -0.235057    0.184030   -1.334530
D   -0.287532    2.394551    0.084300    0.168113    1.286847   -2.150138

按轴排序:

In [21]: df.sort_index(axis=1, ascending=False)
Out[21]: 
                   D         C         B         A
2013-01-01 -0.287532  0.241739  0.056469  0.409000
2013-01-02  2.394551  0.061776 -1.029321  1.302200
2013-01-03  0.084300  1.642294 -0.874806 -0.479307
2013-01-04  0.168113 -0.235057  0.639590  0.362947
2013-01-05  1.286847  0.184030 -0.658483  0.073892
2013-01-06 -2.150138 -1.334530 -0.295086  0.798556

按值排序:

In [22]: df.sort_values(by='B')
Out[22]: 
                   A         B         C         D
2013-01-02  1.302200 -1.029321  0.061776  2.394551
2013-01-03 -0.479307 -0.874806  1.642294  0.084300
2013-01-05  0.073892 -0.658483  0.184030  1.286847
2013-01-06  0.798556 -0.295086 -1.334530 -2.150138
2013-01-01  0.409000  0.056469  0.241739 -0.287532
2013-01-04  0.362947  0.639590 -0.235057  0.168113

选择

注解

虽然在交互式工作中标准Python/NumPy的选择修改表达式直观并且容易上手, 但在生产代码中,我们仍然推荐使用pandas优化过的数据获取方法, .at.iat.loc.iloc

详见关于索引的文档 索引与选择数据 and 多重/高级索引

获取

选择单一一列将会产出一个 Series ,相当于调用 df.A

In [23]: df['A']
Out[23]: 
2013-01-01    0.409000
2013-01-02    1.302200
2013-01-03   -0.479307
2013-01-04    0.362947
2013-01-05    0.073892
2013-01-06    0.798556
Freq: D, Name: A, dtype: float64

使用 [] 来选择,可以按行来对数据进行切片。

In [24]: df[0:3]
Out[24]: 
                   A         B         C         D
2013-01-01  0.409000  0.056469  0.241739 -0.287532
2013-01-02  1.302200 -1.029321  0.061776  2.394551
2013-01-03 -0.479307 -0.874806  1.642294  0.084300

In [25]: df['20130102':'20130104']
Out[25]: 
                   A         B         C         D
2013-01-02  1.302200 -1.029321  0.061776  2.394551
2013-01-03 -0.479307 -0.874806  1.642294  0.084300
2013-01-04  0.362947  0.639590 -0.235057  0.168113
按标签选择

详见 按标签选择

用标签获取横截面数据:

In [26]: df.loc[dates[0]]
Out[26]: 
A    0.409000
B    0.056469
C    0.241739
D   -0.287532
Name: 2013-01-01 00:00:00, dtype: float64

用标签获取多个轴的数据:

In [27]: df.loc[:, ['A', 'B']]
Out[27]: 
                   A         B
2013-01-01  0.409000  0.056469
2013-01-02  1.302200 -1.029321
2013-01-03 -0.479307 -0.874806
2013-01-04  0.362947  0.639590
2013-01-05  0.073892 -0.658483
2013-01-06  0.798556 -0.295086

使用标签切片,两端的标签 都被包含

In [28]: df.loc['20130102':'20130104', ['A', 'B']]
Out[28]: 
                   A         B
2013-01-02  1.302200 -1.029321
2013-01-03 -0.479307 -0.874806
2013-01-04  0.362947  0.639590

降低返回对象的维度:

In [29]: df.loc['20130102', ['A', 'B']]
Out[29]: 
A    1.302200
B   -1.029321
Name: 2013-01-02 00:00:00, dtype: float64

获取一个标量值:

In [30]: df.loc[dates[0], 'A']
Out[30]: 0.4089999194489628

快速获取一个标量值(与先前方法等价):

In [31]: df.at[dates[0], 'A']
Out[31]: 0.4089999194489628
按位置选择

详见 按位置选择

按传入整数的位置选择:

In [32]: df.iloc[3]
Out[32]: 
A    0.362947
B    0.639590
C   -0.235057
D    0.168113
Name: 2013-01-04 00:00:00, dtype: float64

行为类似于NumPy/Python的按整数切片选择:

In [33]: df.iloc[3:5, 0:2]
Out[33]: 
                   A         B
2013-01-04  0.362947  0.639590
2013-01-05  0.073892 -0.658483

风格类似于NumPy/Python的按整数位置的列表选择:

In [34]: df.iloc[[1, 2, 4], [0, 2]]
Out[34]: 
                   A         C
2013-01-02  1.302200  0.061776
2013-01-03 -0.479307  1.642294
2013-01-05  0.073892  0.184030

显性地按行切片:

In [35]: df.iloc[1:3, :]
Out[35]: 
                   A         B         C         D
2013-01-02  1.302200 -1.029321  0.061776  2.394551
2013-01-03 -0.479307 -0.874806  1.642294  0.084300

显性地按列切片:

In [36]: df.iloc[:, 1:3]
Out[36]: 
                   B         C
2013-01-01  0.056469  0.241739
2013-01-02 -1.029321  0.061776
2013-01-03 -0.874806  1.642294
2013-01-04  0.639590 -0.235057
2013-01-05 -0.658483  0.184030
2013-01-06 -0.295086 -1.334530

显性地获得一个值:

In [37]: df.iloc[1, 1]
Out[37]: -1.029321446571742

快速获得一个标量值(等价于上个方法):

In [38]: df.iat[1, 1]
Out[38]: -1.029321446571742
布尔值索引

用单独一列的值来选择数据。

In [39]: df[df.A > 0]
Out[39]: 
                   A         B         C         D
2013-01-01  0.409000  0.056469  0.241739 -0.287532
2013-01-02  1.302200 -1.029321  0.061776  2.394551
2013-01-04  0.362947  0.639590 -0.235057  0.168113
2013-01-05  0.073892 -0.658483  0.184030  1.286847
2013-01-06  0.798556 -0.295086 -1.334530 -2.150138

从一个DataFrame中选择符合布尔条件的值。

In [40]: df[df > 0]
Out[40]: 
                   A         B         C         D
2013-01-01  0.409000  0.056469  0.241739       NaN
2013-01-02  1.302200       NaN  0.061776  2.394551
2013-01-03       NaN       NaN  1.642294  0.084300
2013-01-04  0.362947  0.639590       NaN  0.168113
2013-01-05  0.073892       NaN  0.184030  1.286847
2013-01-06  0.798556       NaN       NaN       NaN

isin() 来过滤:

In [41]: df2 = df.copy()

In [42]: df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three']

In [43]: df2
Out[43]: 
                   A         B         C         D      E
2013-01-01  0.409000  0.056469  0.241739 -0.287532    one
2013-01-02  1.302200 -1.029321  0.061776  2.394551    one
2013-01-03 -0.479307 -0.874806  1.642294  0.084300    two
2013-01-04  0.362947  0.639590 -0.235057  0.168113  three
2013-01-05  0.073892 -0.658483  0.184030  1.286847   four
2013-01-06  0.798556 -0.295086 -1.334530 -2.150138  three

In [44]: df2[df2['E'].isin(['two', 'four'])]
Out[44]: 
                   A         B         C         D     E
2013-01-03 -0.479307 -0.874806  1.642294  0.084300   two
2013-01-05  0.073892 -0.658483  0.184030  1.286847  four
设定

设定自动对齐按索引对齐到数据上的新列:

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

In [46]: s1
Out[46]: 
2013-01-02    1
2013-01-03    2
2013-01-04    3
2013-01-05    4
2013-01-06    5
2013-01-07    6
Freq: D, dtype: int64

In [47]: df['F'] = s1

按标签设定值:

In [48]: df.at[dates[0], 'A'] = 0

按位置设定值:

In [49]: df.iat[0, 1] = 0

用赋一个NumPy数组的方式设定值:

In [50]: df.loc[:, 'D'] = np.array([5] * len(df))

上一个设定操作的结果是:

In [51]: df
Out[51]: 
                   A         B         C  D    F
2013-01-01  0.000000  0.000000  0.241739  5  NaN
2013-01-02  1.302200 -1.029321  0.061776  5  1.0
2013-01-03 -0.479307 -0.874806  1.642294  5  2.0
2013-01-04  0.362947  0.639590 -0.235057  5  3.0
2013-01-05  0.073892 -0.658483  0.184030  5  4.0
2013-01-06  0.798556 -0.295086 -1.334530  5  5.0

通过一个 where 操作来设定值。

In [52]: df2 = df.copy()

In [53]: df2[df2 > 0] = -df2

In [54]: df2
Out[54]: 
                   A         B         C  D    F
2013-01-01  0.000000  0.000000 -0.241739 -5  NaN
2013-01-02 -1.302200 -1.029321 -0.061776 -5 -1.0
2013-01-03 -0.479307 -0.874806 -1.642294 -5 -2.0
2013-01-04 -0.362947 -0.639590 -0.235057 -5 -3.0
2013-01-05 -0.073892 -0.658483 -0.184030 -5 -4.0
2013-01-06 -0.798556 -0.295086 -1.334530 -5 -5.0

缺失数据

pandas主要用 np.nan 值来代表缺失数据。 这在默认情况下不被包括在运算当中。 详见 缺失数据

重新索引可以允许您修改/添加/删除某个特定轴上的索引。这个操作返回源数据的一份拷贝。

In [55]: df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])

In [56]: df1.loc[dates[0]:dates[1], 'E'] = 1

In [57]: df1
Out[57]: 
                   A         B         C  D    F    E
2013-01-01  0.000000  0.000000  0.241739  5  NaN  1.0
2013-01-02  1.302200 -1.029321  0.061776  5  1.0  1.0
2013-01-03 -0.479307 -0.874806  1.642294  5  2.0  NaN
2013-01-04  0.362947  0.639590 -0.235057  5  3.0  NaN

移除任何带有缺失数据的行。

In [58]: df1.dropna(how='any')
Out[58]: 
                 A         B         C  D    F    E
2013-01-02  1.3022 -1.029321  0.061776  5  1.0  1.0

填充缺失数据。

In [59]: df1.fillna(value=5)
Out[59]: 
                   A         B         C  D    F    E
2013-01-01  0.000000  0.000000  0.241739  5  5.0  1.0
2013-01-02  1.302200 -1.029321  0.061776  5  1.0  1.0
2013-01-03 -0.479307 -0.874806  1.642294  5  2.0  5.0
2013-01-04  0.362947  0.639590 -0.235057  5  3.0  5.0

得到值为 nan 的值的布尔值掩码。

In [60]: pd.isna(df1)
Out[60]: 
                A      B      C      D      F      E
2013-01-01  False  False  False  False   True  False
2013-01-02  False  False  False  False  False  False
2013-01-03  False  False  False  False  False   True
2013-01-04  False  False  False  False  False   True

运算符

详见 基本二元运算符