Pandas-2-2-中文文档-一-
Pandas 2.2 中文文档(一)
入门指南
安装
使用 conda?
pandas 是Anaconda发行版的一部分,可以使用 Anaconda 或 Miniconda 进行安装:
conda install -c conda-forge pandas
更喜欢 pip 吗?
可以通过 pip 从PyPI安装 pandas。
pip install pandas
深入的说明?
想要安装特定版本?从源代码安装?请查看高级安装页面。
了解更多
pandas 简介
pandas 处理什么类型的数据?直达教程…
在处理表格数据(如存储在电子表格或数据库中的数据)时,pandas 是您的正确工具。pandas 将帮助您探索、清理和处理数据。在 pandas 中,数据表称为DataFrame
。
到介绍教程 到用户指南 如何读取和写入表格数据?直达教程…
pandas 原生支持与许多文件格式或数据源的集成(csv、excel、sql、json、parquet 等)。从每个数据源导入数据的功能由具有前缀read_*
的函数提供。类似地,to_*
方法用于存储数据。
到介绍教程 到用户指南 如何选择表的子集?直达教程…
需要选择或过滤特定行和/或列?根据条件过滤数据?pandas 提供了用于切片、选择和提取所需数据的方法。
到介绍教程 到用户指南 如何在 pandas 中创建图表?直达教程…
pandas 可以直接绘制您的数据,使用 Matplotlib 的强大功能。您可以选择与您的数据相对应的绘图类型(散点图、柱状图、箱线图等)。
到介绍教程 到用户指南 如何根据现有列创建新列?直达教程…
没有必要遍历数据表的所有行来进行计算。对列的数据操作是逐个元素进行的。根据其他列中的现有数据向DataFrame
添加列非常简单。
进入教程 进入用户指南 如何计算摘要统计量? 直接到教程…
基本统计量(均值、中位数、最小值、最大值、计数等)很容易计算。这些统计量或自定义的聚合可以应用于整个数据集、数据的滑动窗口,或者按类别分组。后者也被称为分拆-应用-合并方法。
进入教程 进入用户指南 如何改变表格的布局? 直接到教程…
在多种方式下改变数据表的结构。您可以将数据表从宽格式转换为长格式或整洁格式进行melt()
,或者从长格式转换为宽格式进行pivot()
。带有内置聚合函数,可以使用单个命令创建透视表。
进入教程 进入用户指南 如何合并来自多个表的数据? 直接到教程…
可以沿着列或行方向连接多个表格,因为提供了类似数据库的连接/合并操作来组合多个数据表。
进入教程 进入用户指南 如何处理时间序列数据? 直接到教程…
pandas 对时间序列有很好的支持,并且拥有一套广泛的工具用于处理日期、时间和时间索引数据。
进入教程 进入用户指南 如何操作文本数据? 直接到教程…
数据集不仅包含数值数据。pandas 提供了广泛的函数来清理文本数据并从中提取有用信息。
进入介绍教程 进入用户指南 ## 来源…
你熟悉其他用于操作表格数据的软件吗?学习与你已经了解的软件相比较的 pandas 等效操作:
R 编程语言提供了data.frame
数据结构和多个包,例如 tidyverse 使用并扩展data.frame
以方便处理数据,类似于 pandas。
了解更多
已经熟悉SELECT
、GROUP BY
、JOIN
等操作了吗?大多数这些 SQL 操作在 pandas 中都有对应的操作。
了解更多
STATA 统计软件套件中包含的data set
与 pandas DataFrame
对应。许多来自 STATA 的操作在 pandas 中都有对应的操作。
了解更多
使用 Excel 或其他电子表格程序的用户会发现许多概念可以转移到 pandas。
了解更多
SAS 统计软件套件也提供了与 pandas DataFrame
对应的data set
。此外,SAS 的向量化操作、过滤、字符串处理等操作在 pandas 中也有类似功能。
了解更多
教程
想要快速了解 pandas 功能,请参阅 10 分钟入门 pandas。
您还可以参考 pandas 的速查表,以获得关于使用 pandas 操纵数据的简明指南。
社区制作了各种在线教程。一些材料列在社区贡献的社区教程中。
安装
使用 conda?
pandas 是Anaconda发行版的一部分,可以使用 Anaconda 或 Miniconda 进行安装:
conda install -c conda-forge pandas
偏好 pip?
可以通过 pip 从PyPI安装 pandas。
pip install pandas
深入的说明?
安装特定版本?从源代码安装?查看高级安装页面。
了解更多
pandas 入门
pandas 处理什么类型的数据?直接进入教程…
当处理表格数据时,如存储在电子表格或数据库中的数据时,pandas 是您的正确工具。pandas 将帮助您探索、清理和处理您的数据。在 pandas 中,数据表被称为DataFrame
。
进入教程 查看用户指南 如何读取和写入表格数据?直达教程…
pandas 支持与许多文件格式或数据源的集成(csv、excel、sql、json、parquet 等)。从这些数据源导入数据由带有前缀read_*
的函数提供。类似地,使用to_*
方法来存储数据。
进入教程 查看用户指南 如何选择表格的子集?直达教程…
选择或过滤特定的行和/或列?在条件上过滤数据?在 pandas 中有用于切片、选择和提取所需数据的方法。
进入教程 查看用户指南 如何在 pandas 中创建图形?直达教程…
pandas 提供了直接绘制数据的功能,利用了 Matplotlib 的强大功能。你可以选择与你的数据相对应的图形类型(散点图、条形图、箱线图等)。
进入教程 查看用户指南 如何根据现有列创建新列?直达教程…
不需要遍历数据表的所有行来进行计算。对列进行的数据操作是逐元素进行的。根据其他列中的现有数据添加列到DataFrame
非常简单。
进入教程 查看用户指南 如何计算汇总统计信息?直达教程…
基本统计(均值、中位数、最小值、最大值、计数等)可轻松计算。这些或自定义聚合可以应用于整个数据集、数据的滑动窗口,或按类别分组。后者也被称为拆分-应用-组合方法。
进入教程介绍 进入用户指南 如何重塑表格布局? 直达教程…
以多种方式更改数据表的结构。你可以将你的数据表从宽格式转换为长/整洁格式(melt()
),或者从长格式转换为宽格式(pivot()
)。内置的聚合函数可以一次性创建一个数据透视表。
进入教程介绍 进入用户指南 如何组合来自多个表格的数据? 直达教程…
多个表格可以沿列和行进行连接,就像数据库的连接/合并操作一样,提供了用于合并多个数据表的操作。
进入教程介绍 进入用户指南 如何处理时间序列数据? 直达教程…
pandas 对于时间序列具有很好的支持,并且有一套丰富的工具用于处理日期、时间和以时间为索引的数据。
进入教程介绍 进入用户指南 如何操作文本数据? 直达教程…
数据集不仅包含数值数据。pandas 提供了广泛的函数来清理文本数据,并从中提取有用信息。
进入教程介绍 进入用户指南 ## 从哪里来…
你是否熟悉其他用于操作表格数据的软件?学习与你已知软件相比的 pandas 等效操作:
R 编程语言提供了 data.frame
数据结构以及多个包,例如 tidyverse 使用并扩展了 data.frame
,提供了类似于 pandas 的便捷数据处理功能。
了解更多
对SELECT
、GROUP BY
、JOIN
等已经很熟悉了吗?大多数这些 SQL 操作在 pandas 中都有对应的操作。
了解更多
STATA统计软件套件中包含的数据集
对应于 pandas 的DataFrame
。许多从 STATA 熟知的操作在 pandas 中都有对应的操作。
了解更多
Excel或其他电子表格程序的用户会发现,许多概念都可以转移到 pandas 中。
了解更多
SAS统计软件套件也提供了与 pandas 的DataFrame
相对应的数据集
。此外,SAS 的向量化操作、过滤、字符串处理等操作在 pandas 中也有类似的功能。
了解更多
教程
想要快速了解 pandas 功能,请参阅 10 分钟入门 pandas。
您也可以参考 pandas 的速查表,以获得使用 pandas 进行数据操作的简洁指南。
社区制作了各种在线教程。一些材料被列在社区贡献的社区教程中。
安装
安装 pandas 的最简单方法是作为Anaconda发行版的一部分安装,这是一个用于数据分析和科学计算的跨平台发行版。Conda包管理器是大多数用户推荐的安装方法。
还提供了从源代码安装(#install-source)、从 PyPI 安装(#install-pypi)或安装开发版本(#install-dev)的说明。
Python 版本支持
官方支持 Python 3.9、3.10、3.11 和 3.12。
安装 pandas
使用 Anaconda 安装
对于新手用户,安装 Python、pandas 和构成PyData堆栈(SciPy、NumPy、Matplotlib等)的包的最简单方法是使用Anaconda,这是一个跨平台(Linux、macOS、Windows)的 Python 发行版,用于数据分析和科学计算。Anaconda 的安装说明在这里。 ### 使用 Miniconda 安装
对于有经验的 Python 用户,推荐使用Miniconda安装 pandas。Miniconda 允许您创建一个相对于 Anaconda 更小、独立的 Python 安装,并使用Conda包管理器安装其他包并为您的安装创建虚拟环境。Miniconda 的安装说明在这里。
下一步是创建一个新的 conda 环境。conda 环境类似于一个允许您指定特定版本的 Python 和一组库的虚拟环境。从终端窗口运行以下命令。
conda create -c conda-forge -n name_of_my_env python pandas
这将创建一个仅安装了 Python 和 pandas 的最小环境。要进入这个环境,请运行。
source activate name_of_my_env
# On Windows
activate name_of_my_env
``` ### 从 PyPI 安装
可以通过 pip 从[PyPI](https://pypi.org/project/pandas)安装 pandas。
```py
pip install pandas
注意
您必须拥有pip>=19.3
才能从 PyPI 安装。
注意
建议从虚拟环境中安装和运行 pandas,例如,使用 Python 标准库的venv
pandas 也可以安装带有可选依赖项集以启用某些功能。例如,要安装带有读取 Excel 文件的可选依赖项的 pandas。
pip install "pandas[excel]"
可以在依赖部分找到可以安装的全部额外功能列表。
处理 ImportError
如果遇到 ImportError
,通常意味着 Python 在可用库列表中找不到 pandas。Python 内部有一个目录列表,用于查找软件包。您可以通过以下方式获取这些目录。
import sys
sys.path
您可能遇到此错误的一种方法是,如果您的系统上安装了多个 Python,并且您当前使用的 Python 安装中没有安装 pandas,则可能会遇到此错误。在 Linux/Mac 上,您可以在终端上运行 which python
,它将告诉您当前正在使用哪个 Python 安装。如果是类似“/usr/bin/python”的东西,则表示您正在使用系统中的 Python,这是不推荐的。
强烈建议使用 conda
,以便快速安装和更新软件包和依赖项。您可以在此文档中找到有关 pandas 的简单安装说明。
从源代码安装
请参阅贡献指南以获取有关从 git 源代码树构建的完整说明。此外,如果您希望创建 pandas 开发环境,请参阅创建开发环境。 ### 安装 pandas 的开发版本
安装开发版本是最快的方法:
-
尝试一个新功能,该功能将在下一个发布中发布(即,从最近合并到主分支的拉取请求中提取的功能)。
-
检查您遇到的错误是否在上次发布之后修复。
开发版本通常每天上传到 anaconda.org 的 PyPI 注册表的 scientific-python-nightly-wheels 索引中。您可以通过运行以下命令进行安装。
pip install --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple pandas
请注意,您可能需要卸载现有版本的 pandas 才能安装开发版本。
pip uninstall pandas -y
运行测试套件
pandas 配备有一套详尽的单元测试。运行测试所需的软件包可以使用 pip install "pandas[test]"
进行安装。要从 Python 终端运行测试。
>>> import pandas as pd
>>> pd.test()
running: pytest -m "not slow and not network and not db" /home/user/anaconda3/lib/python3.9/site-packages/pandas
============================= test session starts ==============================
platform linux -- Python 3.9.7, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/user
plugins: dash-1.19.0, anyio-3.5.0, hypothesis-6.29.3
collected 154975 items / 4 skipped / 154971 selected
........................................................................ [ 0%]
........................................................................ [ 99%]
....................................... [100%]
==================================== ERRORS ====================================
=================================== FAILURES ===================================
=============================== warnings summary ===============================
=========================== short test summary info ============================
= 1 failed, 146194 passed, 7402 skipped, 1367 xfailed, 5 xpassed, 197 warnings, 10 errors in 1090.16s (0:18:10) =
注意
这只是显示的信息示例。测试失败并不一定表示 pandas 安装有问题。
依赖项
必需的依赖项
pandas 需要以下依赖项。
软件包 | 最低支持版本 |
---|---|
NumPy | 1.22.4 |
python-dateutil | 2.8.2 |
pytz | 2020.1 |
| tzdata | 2022.7 | ### 可选依赖项
pandas 有许多可选依赖项,仅用于特定方法。例如,pandas.read_hdf()
需要 pytables
包,而 DataFrame.to_markdown()
需要 tabulate
包。如果未安装可选依赖项,则在调用需要该依赖项的方法时,pandas 将引发 ImportError
。
如果使用 pip,可选的 pandas 依赖项可以作为可选额外项(例如 pandas[performance, aws]
)安装或在文件中管理(例如 requirements.txt 或 pyproject.toml)。所有可选依赖项都可以通过 pandas[all]
安装,特定的依赖项集在下面的各节中列出。
性能依赖项(推荐)
注意
鼓励您安装这些库,因为它们提供了速度改进,特别是在处理大型数据集时。
可通过 pip install "pandas[performance]"
进行安装。
依赖项 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
numexpr | 2.8.4 | 性能 | 通过使用多个核心以及智能分块和缓存来加速某些数值运算 |
bottleneck | 1.3.6 | 性能 | 通过使用专门的 cython 程序加速某些类型的 nan ,从而实现大幅加速。 |
numba | 0.56.4 | 性能 | 用��接受 engine="numba" 的操作的替代执行引擎,使用 JIT 编译器将 Python 函数转换为优化的机器代码,使用 LLVM 编译器实现大幅优化。 |
可视化
可通过 pip install "pandas[plot, output-formatting]"
进行安装。
依赖项 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
matplotlib | 3.6.3 | 绘图 | 绘图库 |
Jinja2 | 3.1.2 | 输出格式化 | 与 DataFrame.style 一起使用的条件格式化 |
tabulate | 0.9.0 | 输出格式化 | 以 Markdown 友好的格式打印(参见 tabulate) |
计算
可通过 pip install "pandas[computation]"
进行安装。
依赖项 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
SciPy | 1.10.0 | 计算 | 各种统计函数 |
xarray | 2022.12.0 | 计算 | 用于 N 维数据的类似于 pandas 的 API |
Excel 文件
可通过 pip install "pandas[excel]"
进行安装。
依赖项 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
xlrd | 2.0.1 | excel | 读取 Excel |
xlsxwriter | 3.0.5 | excel | 写入 Excel |
openpyxl | 3.1.0 | excel | 读取/写入 xlsx 文件 |
pyxlsb | 1.0.10 | excel | 读取 xlsb 文件 |
python-calamine | 0.1.7 | excel | 读取 xls/xlsx/xlsb/ods 文件 |
HTML
可通过 pip install "pandas[html]"
进行安装。
依赖 | 最低版本 | pip 额外组件 | 注释 |
---|---|---|---|
BeautifulSoup4 | 4.11.2 | html | 用于 read_html 的 HTML 解析器 |
html5lib | 1.1 | html | 用于 read_html 的 HTML 解析器 |
lxml | 4.9.2 | html | 用于 read_html 的 HTML 解析器 |
使用顶层 read_html()
函数,需要以下库组合之一:
-
只需要 lxml,尽管请查看 HTML 表解析 了解为什么你可能 不 应该采用这种方法。
警告
-
如果你安装了 BeautifulSoup4,你必须安装 lxml 或者 html5lib,或者两者都安装。只有安装了 BeautifulSoup4,
read_html()
才会 不 起作用。 -
强烈建议阅读 HTML 表解析陷阱。它解释了上述三个库的安装和使用相关问题。
XML
通过 pip install "pandas[xml]"
安装。
依赖 | 最低版本 | pip 额外组件 | 注释 |
---|---|---|---|
lxml | 4.9.2 | xml | read_xml 的 XML 解析器和 to_xml 的树生成器 |
SQL 数据库
传统驱动可以通过 pip install "pandas[postgresql, mysql, sql-other]"
安装。
依赖 | 最低版本 | pip 额外组件 | 注释 |
---|---|---|---|
SQLAlchemy | 2.0.0 | postgresql, mysql, sql-other | 除 sqlite 外其他数据库的 SQL 支持 |
psycopg2 | 2.9.6 | postgresql | 用于 sqlalchemy 的 PostgreSQL 引擎 |
pymysql | 1.0.2 | mysql | 用于 sqlalchemy 的 MySQL 引擎 |
adbc-driver-postgresql | 0.8.0 | postgresql | PostgreSQL 的 ADBC 驱动程序 |
adbc-driver-sqlite | 0.8.0 | sql-other | SQLite 的 ADBC 驱动程序 |
其他数据源
通过 pip install "pandas[hdf5, parquet, feather, spss, excel]"
安装。
依赖 | 最低版本 | pip 额外组件 | 注释 |
---|---|---|---|
PyTables | 3.8.0 | hdf5 | 基于 HDF5 的读取 / 写入 |
blosc | 1.21.3 | hdf5 | HDF5 压缩;仅适用于 conda |
zlib | hdf5 | HDF5 压缩 | |
fastparquet | 2022.12.0 | Parquet 读取 / 写入(pyarrow 是默认) | |
pyarrow | 10.0.1 | parquet, feather | Parquet、ORC 和 feather 读取 / 写入 |
pyreadstat | 1.2.0 | spss | SPSS 文件(.sav)读取 |
odfpy | 1.4.1 | excel | Open document format (.odf, .ods, .odt) 读取 / 写入 |
警告
- 如果你想使用
read_orc()
,强烈建议使用 conda 安装 pyarrow。如果 pyarrow 是从 pypi 安装的,可能会导致read_orc()
失败,并且read_orc()
与 Windows 操作系统不兼容。
访问云端数据
使用 pip install "pandas[fss, aws, gcp]"
可安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
fsspec | 2022.11.0 | fss, gcp, aws | 处理除简单本地和 HTTP 外的文件(s3fs、gcsfs 的必需依赖)。 |
gcsfs | 2022.11.0 | gcp | 谷歌云存储访问 |
pandas-gbq | 0.19.0 | gcp | 谷歌大数据查询访问 |
s3fs | 2022.11.0 | aws | 亚马逊 S3 访问 |
剪贴板
使用 pip install "pandas[clipboard]"
可安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
PyQt4/PyQt5 | 5.15.9 | clipboard | 剪贴板 I/O |
qtpy | 2.3.0 | clipboard | 剪贴板 I/O |
注意
根据操作系统的不同,可能需要安装系统级软件包。在 Linux 上,要使剪贴板正常工作,必须安装其中一个命令行工具 xclip
或 xsel
。
压缩
使用 pip install "pandas[compression]"
可安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
Zstandard | 0.19.0 | compression | Zstandard 压缩 |
联盟标准
使用 pip install "pandas[consortium-standard]"
可安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|
| dataframe-api-compat | 0.1.7 | consortium-standard | 基于 pandas 的联盟标准兼容实现 | ## Python 版本支持
官方支持 Python 3.9、3.10、3.11 和 3.12。
安装 pandas
使用 Anaconda 安装
对于新手用户,安装 Python、pandas 以及构成 PyData 栈(SciPy、NumPy、Matplotlib 等)的软件包最简单的方法是使用 Anaconda,这是一个跨平台(Linux、macOS、Windows)的数据分析和科学计算 Python 发行版。Anaconda 的安装说明 可在此找到。 ### 使用 Miniconda 安装
对于有 Python 经验的用户,推荐使用Miniconda安装 pandas。Miniconda 允许您创建一个最小的、独立的 Python 安装,与 Anaconda 相比,并使用Conda包管理器安装其他包并为您的安装创建虚拟环境。有关 Miniconda 的安装说明可以在这里找到。
下一步是创建一个新的 conda 环境。conda 环境类似于一个允许您指定特定 Python 版本和一组库的虚拟环境。从终端窗口运行以下命令。
conda create -c conda-forge -n name_of_my_env python pandas
这将创建一个只安装了 Python 和 pandas 的最小环境。要进入此环境,请运行。
source activate name_of_my_env
# On Windows
activate name_of_my_env
``` ### 从 PyPI 安装
可以通过 pip 从[PyPI](https://pypi.org/project/pandas)安装 pandas。
```py
pip install pandas
注意
您必须拥有pip>=19.3
才能从 PyPI 安装。
注意
建议安装并从虚拟环境中运行 pandas,例如,使用 Python 标准库的venv。
pandas 也可以安装一组可选依赖项,以启用某些功能。例如,要安装带有可选依赖项以读取 Excel 文件的 pandas。
pip install "pandas[excel]"
可以在依赖部分找到可以安装的全部额外内容列表。
处理 ImportErrors
如果遇到ImportError
,通常意味着 Python 在可用库列表中找不到 pandas。Python 内部有一个目录列表,用于查找包。您可以通过以下方式获取这些目录。
import sys
sys.path
您可能遇到此错误的一种方式是,如果您的系统上有多个 Python 安装,并且您当前使用的 Python 安装中没有安装 pandas。在 Linux/Mac 上,您可以在终端上运行which python
,它会告诉您正在使用哪个 Python 安装。如果类似于“/usr/bin/python”,则您正在使用系统中的 Python,这是不推荐的。
强烈建议使用conda
进行快速安装和包和依赖项更新。您可以在此文档中找到有关 pandas 的简单安装说明。
从源代码安装
请查看贡献指南以获取有关从 git 源代码树构建的完整说明。此外,如果您希望创建 pandas 开发环境,请查看创建开发环境。 ### 安装 pandas 的开发版本
安装开发版本是最快的方法:
-
尝试一个将在下一个发布中提供的新功能(即,最近合并到主分支的拉取请求中的功能)。
-
检查您遇到的错误是否在上一个版本中已修复。
开发版本通常每天上传到 anaconda.org 的 PyPI 注册表的 scientific-python-nightly-wheels 索引中。您可以通过运行来安装它。
pip install --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple pandas
请注意,您可能需要卸载现有版本的 pandas 才能安装开发版本。
pip uninstall pandas -y
``` ### 使用 Anaconda 安装
对于新手用户,安装 Python、pandas 和构成[PyData](https://pydata.org/)堆栈([SciPy](https://scipy.org/)、[NumPy](https://numpy.org/)、[Matplotlib](https://matplotlib.org/)等)的包最简单的方法是使用[Anaconda](https://docs.continuum.io/free/anaconda/),这是一个跨平台(Linux、macOS、Windows)的用于数据分析和科学计算的 Python 发行版。有关 Anaconda 的安装说明[请参见此处](https://docs.continuum.io/free/anaconda/install/)。
### 使用 Miniconda 安装
对于有 Python 经验的用户,推荐使用[Miniconda](https://docs.conda.io/en/latest/miniconda.html)安装 pandas。Miniconda 允许您创建一个最小、独立的 Python 安装,与 Anaconda 相比,使用[Conda](https://conda.io/en/latest/)包管理器安装额外的包并为您的安装创建虚拟环境。有关 Miniconda 的安装说明[请参见此处](https://docs.conda.io/en/latest/miniconda.html)。
下一步是创建一个新的 conda 环境。conda 环境类似于一个允许您指定特定 Python 版本和一组库的虚拟环境。从终端窗口运行以下命令。
```py
conda create -c conda-forge -n name_of_my_env python pandas
这将创建一个只安装了 Python 和 pandas 的最小环境。要进入此环境,请运行。
source activate name_of_my_env
# On Windows
activate name_of_my_env
从 PyPI 安装
可以通过pip从 PyPI 安装 pandas。
pip install pandas
注意
您必须拥有pip>=19.3
才能从 PyPI 安装。
注意
建议在虚拟环境中安装和运行 pandas,例如,使用 Python 标准库的venv。
pandas 也可以安装带有可选依赖项集合以启用某些功能。例如,要安装带有可选依赖项以读取 Excel 文件的 pandas。
pip install "pandas[excel]"
可以在依赖部分找到可以安装的全部额外功能列表。
处理 ImportErrors
如果遇到ImportError
,通常意味着 Python 在可用库列表中找不到 pandas。Python 内部有一个目录列表,用于查找包。您可以通过以下方式获取这些目录。
import sys
sys.path
您可能遇到此错误的一种方式是,如果您的系统上有多个 Python 安装,并且您当前使用的 Python 安装中没有安装 pandas。在 Linux/Mac 上,您可以在终端上运行which python
,它会告诉您当前使用的 Python 安装。如果显示类似“/usr/bin/python”的内容,则表示您正在使用系统中的 Python,这是不推荐的。
强烈建议使用conda
,以快速安装和更新包和依赖项。您可以在此文档中找到 pandas 的简单安装说明。
从源代码安装
查看贡献指南以获取有关从 git 源代码树构建的完整说明。此外,如果您希望创建一个 pandas 开发环境,请查看创建开发环境。
安装 pandas 的开发版本
安装开发版本是最快的方式:
-
尝试一个将在下一个版本中发布的新功能(即,最近合并到主分支的拉取请求中的功能)。
-
检查您遇到的错误是否自上次发布以来已修复。
开发版本通常每天上传到 anaconda.org 的 PyPI 注册表的 scientific-python-nightly-wheels 索引中。您可以通过运行以下命令来安装。
pip install --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple pandas
请注意,您可能需要卸载现有版本的 pandas 才能安装开发版本。
pip uninstall pandas -y
运行测试套件
pandas 配备了一套详尽的单元测试。运行测试所需的包可以通过pip install "pandas[test]"
安装。要从 Python 终端运行测试。
>>> import pandas as pd
>>> pd.test()
running: pytest -m "not slow and not network and not db" /home/user/anaconda3/lib/python3.9/site-packages/pandas
============================= test session starts ==============================
platform linux -- Python 3.9.7, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /home/user
plugins: dash-1.19.0, anyio-3.5.0, hypothesis-6.29.3
collected 154975 items / 4 skipped / 154971 selected
........................................................................ [ 0%]
........................................................................ [ 99%]
....................................... [100%]
==================================== ERRORS ====================================
=================================== FAILURES ===================================
=============================== warnings summary ===============================
=========================== short test summary info ============================
= 1 failed, 146194 passed, 7402 skipped, 1367 xfailed, 5 xpassed, 197 warnings, 10 errors in 1090.16s (0:18:10) =
注意
这只是显示的信息示例。测试失败并不一定表示 pandas 安装有问题。
依赖关系
必需依赖
pandas 需要以下依赖项。
包 | 最低支持版本 |
---|---|
NumPy | 1.22.4 |
python-dateutil | 2.8.2 |
pytz | 2020.1 |
| tzdata | 2022.7 | ### 可选依赖
pandas 有许多可选依赖项,仅用于特定方法。例如,pandas.read_hdf()
需要pytables
包,而DataFrame.to_markdown()
需要tabulate
包。如果未安装可选依赖项,则在调用需要该依赖项的方法时,pandas 将引发ImportError
。
如果使用 pip,可以将可选的 pandas 依赖项安装或管理到文件中(例如 requirements.txt 或 pyproject.toml),作为可选的额外功能(例如 pandas[performance, aws]
)。所有可选依赖项均可使用 pandas[all]
安装,具体的依赖项集合列在下面的各个部分中。
性能依赖项(推荐)
注意
强烈建议您安装这些库,因为它们提供了速度改进,特别是在处理大数据集时。
使用 pip install "pandas[performance]"
进行安装
依赖项 | 最低版本 | pip extra | 注释 |
---|---|---|---|
numexpr | 2.8.4 | performance | 通过使用多个核心以及智能分块和缓存来加速某些数值运算。 |
bottleneck | 1.3.6 | performance | 通过使用专门的 cython 程序加速某些类型的 nan ,以实现大幅加速。 |
numba | 0.56.4 | performance | 用于接受 engine="numba" 的操作的替代执行引擎,使用 JIT 编译器将 Python 函数转换为优化的机器码,使用 LLVM 编译器实现大幅度优化。 |
可视化
使用 pip install "pandas[plot, output-formatting]"
进行安装。
依赖项 | 最低版本 | pip extra | 注释 |
---|---|---|---|
matplotlib | 3.6.3 | plot | 绘图库 |
Jinja2 | 3.1.2 | output-formatting | 使用 DataFrame.style 进行条件格式化 |
tabulate | 0.9.0 | output-formatting | 以 Markdown 友好的格式打印(参见 tabulate) |
计算
使用 pip install "pandas[computation]"
进行安装。
依赖项 | 最低版本 | pip extra | 注释 |
---|---|---|---|
SciPy | 1.10.0 | computation | 杂项统计函数 |
xarray | 2022.12.0 | computation | 用于 N 维数据的类似 pandas API |
Excel 文件
使用 pip install "pandas[excel]"
进行安装。
依赖项 | 最低版本 | pip extra | 注释 |
---|---|---|---|
xlrd | 2.0.1 | excel | 读取 Excel |
xlsxwriter | 3.0.5 | excel | 写入 Excel |
openpyxl | 3.1.0 | excel | 用于读取 / 写入 xlsx 文件 |
pyxlsb | 1.0.10 | excel | 用于读取 xlsb 文件 |
python-calamine | 0.1.7 | excel | 用于读取 xls/xlsx/xlsb/ods 文件 |
HTML
使用 pip install "pandas[html]"
进行安装。
依赖项 | 最低版本 | pip extra | 注释 |
---|---|---|---|
BeautifulSoup4 | 4.11.2 | html | 用于 read_html 的 HTML 解析器 |
html5lib | 1.1 | html | 用于 read_html 的 HTML 解析器 |
lxml | 4.9.2 | html | 用于 read_html 的 HTML 解析器 |
若要使用顶层 read_html()
函数,需要以下其中一种组合的库:
-
只有 lxml,尽管参阅 HTML 表格解析 可了解为什么您可能 不应该 采用这种方法。
警告
-
如果安装了 BeautifulSoup4,您必须安装 lxml 或 html5lib 或两者都安装。只安装 BeautifulSoup4 将 不会 使
read_html()
正常工作。 -
强烈建议阅读 HTML 表格解析注意事项。它解释了关于上述三个库的安装和使用的问题。
XML
可通过 pip install "pandas[xml]"
进行安装。
依赖 | 最低版本 | pip extra | 注释 |
---|---|---|---|
lxml | 4.9.2 | xml | 用于 read_xml 的 XML 解析器,用于 to_xml 的树构建器 |
SQL 数据库
传统驱动程序可通过 pip install "pandas[postgresql, mysql, sql-other]"
进行安装。
依赖 | 最低版本 | pip extra | 注释 |
---|---|---|---|
SQLAlchemy | 2.0.0 | postgresql, mysql, sql-other | 除 sqlite 外的数据库的 SQL 支持 |
psycopg2 | 2.9.6 | postgresql | SQLAlchemy 的 PostgreSQL 引擎 |
pymysql | 1.0.2 | mysql | SQLAlchemy 的 MySQL 引擎 |
adbc-driver-postgresql | 0.8.0 | postgresql | 用于 PostgreSQL 的 ADBC 驱动程序 |
adbc-driver-sqlite | 0.8.0 | sql-other | 用于 SQLite 的 ADBC 驱动程序 |
其他数据源
可通过 pip install "pandas[hdf5, parquet, feather, spss, excel]"
进行安装。
依赖 | 最低版本 | pip extra | 注释 |
---|---|---|---|
PyTables | 3.8.0 | hdf5 | 基于 HDF5 的读取/写入 |
blosc | 1.21.3 | hdf5 | HDF5 的压缩;仅在 conda 上可用 |
zlib | hdf5 | HDF5 的压缩 | |
fastparquet | 2022.12.0 | Parquet 的读取/写入(pyarrow 是默认值) | |
pyarrow | 10.0.1 | parquet, feather | Parquet、ORC 和 feather 的读取/写入 |
pyreadstat | 1.2.0 | spss | SPSS 文件(.sav)的读取 |
odfpy | 1.4.1 | excel | Open document format (.odf, .ods, .odt) 读取/写入 |
警告
- 如果您想使用
read_orc()
,强烈建议使用 conda 安装 pyarrow。如果从 pypi 安装了 pyarrow,read_orc()
可能会失败,并且read_orc()
不兼容 Windows 操作系统。
访问云中的数据
可通过 pip install "pandas[fss, aws, gcp]"
进行安装。
依赖 | 最低版本 | pip extra | 注释 |
---|---|---|---|
fsspec | 2022.11.0 | fss, gcp, aws | 处理除简单本地和 HTTP 之外的文件(s3fs、gcsfs 的必需依赖)。 |
gcsfs | 2022.11.0 | gcp | 谷歌云存储访问 |
pandas-gbq | 0.19.0 | gcp | 谷歌 Big Query 访问 |
s3fs | 2022.11.0 | aws | 亚马逊 S3 访问 |
剪贴板
可通过 pip install "pandas[clipboard]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
PyQt4/PyQt5 | 5.15.9 | clipboard | 剪贴板 I/O |
qtpy | 2.3.0 | clipboard | 剪贴板 I/O |
注意
根据操作系统的不同,可能需要安装系统级软件包。在 Linux 上,剪贴板要正常运行,系统必须安装 xclip
或 xsel
中的一个 CLI 工具。
压缩
可通过 pip install "pandas[compression]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
Zstandard | 0.19.0 | compression | Zstandard 压缩 |
联盟标准
可通过 pip install "pandas[consortium-standard]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|
| dataframe-api-compat | 0.1.7 | consortium-standard | 基于 pandas 的联盟标准兼容实现 | ### 必需依赖
pandas 需要以下依赖。
包 | 最低支持版本 |
---|---|
NumPy | 1.22.4 |
python-dateutil | 2.8.2 |
pytz | 2020.1 |
tzdata | 2022.7 |
可选依赖
pandas 有许多仅用于特定方法的可选依赖。例如,pandas.read_hdf()
需要 pytables
包,而 DataFrame.to_markdown()
需要 tabulate
包。如果未安装可选依赖,当调用需要该依赖的方法时,pandas 将引发 ImportError
。
如果使用 pip,可选的 pandas 依赖可以作为可选额外项(例如 pandas[performance, aws]
)安装或管理在文件中(例如 requirements.txt 或 pyproject.toml),所有可选依赖可以通过 pandas[all]
进行安装,特定的依赖集在下面的部分中列出。
性能依赖(推荐)
注意
强烈建议安装这些库,因为它们提供了速度改进,特别是在处理大数据集时。
可通过 pip install "pandas[performance]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
numexpr | 2.8.4 | performance | 通过使用多核心、智能分块和缓存来加速某些数值操作 |
bottleneck | 1.3.6 | performance | 通过使用专门的 cython 程序加速某些类型的 nan ,实现大幅加速。 |
numba | 0.56.4 | performance | 用于接受 engine="numba" 的操作的替代执行引擎,使用 JIT 编译器将 Python 函数转换为优化的机器码,使用 LLVM 编译器。 |
可视化
可通过 pip install "pandas[plot, output-formatting]"
进行安装。
依赖 | 最低版本 | pip 额外 | 备注 |
---|---|---|---|
matplotlib | 3.6.3 | plot | 绘图库 |
Jinja2 | 3.1.2 | output-formatting | 使用 DataFrame.style 进行条件格式化 |
tabulate | 0.9.0 | output-formatting | 以 Markdown 友好格式打印(参见 tabulate) |
计算
可通过 pip install "pandas[computation]"
进行安装。
依赖 | 最���版本 | pip 额外 | 备注 |
---|---|---|---|
SciPy | 1.10.0 | computation | 各种统计函数 |
xarray | 2022.12.0 | computation | 用于 N 维数据的类似 pandas API |
Excel 文件
可通过 pip install "pandas[excel]"
进行安装。
依赖 | 最低版本 | pip 额外 | 备注 |
---|---|---|---|
xlrd | 2.0.1 | excel | Excel 读取 |
xlsxwriter | 3.0.5 | excel | Excel 写入 |
openpyxl | 3.1.0 | excel | 用于 xlsx 文件的读取/写入 |
pyxlsb | 1.0.10 | excel | 用于 xlsb 文件的读取 |
python-calamine | 0.1.7 | excel | 用于 xls/xlsx/xlsb/ods 文件的读取 |
HTML
可通过 pip install "pandas[html]"
进行安装。
依赖 | 最低版本 | pip 额外 | 备注 |
---|---|---|---|
BeautifulSoup4 | 4.11.2 | html | 用于 read_html 的 HTML 解析器 |
html5lib | 1.1 | html | 用于 read_html 的 HTML 解析器 |
lxml | 4.9.2 | html | 用于 read_html 的 HTML 解析器 |
使用顶层 read_html()
函数需要以下库中的一种或多种组合:
-
仅 lxml,尽管请参阅 HTML 表格解析 了解为什么您可能应该 不要 采用这种方法。
警告
-
如果安装了 BeautifulSoup4,则必须安装 lxml 或 html5lib 或两者都安装。仅安装 BeautifulSoup4 不会 使
read_html()
起作用。 -
强烈建议阅读 HTML Table Parsing gotchas。它解释了关于安装和使用上述三个库的问题。
XML
使用 pip install "pandas[xml]"
可以安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
lxml | 4.9.2 | xml | 用于 read_xml 的 XML 解析器和用于 to_xml 的树生成器 |
SQL 数据库
传统驱动程序可以使用 pip install "pandas[postgresql, mysql, sql-other]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
SQLAlchemy | 2.0.0 | postgresql, mysql, sql-other | 除了 sqlite 外其他数据库的 SQL 支持 |
psycopg2 | 2.9.6 | postgresql | SQLAlchemy 的 PostgreSQL 引擎 |
pymysql | 1.0.2 | mysql | SQLAlchemy 的 MySQL 引擎 |
adbc-driver-postgresql | 0.8.0 | postgresql | 用于 PostgreSQL 的 ADBC 驱动程序 |
adbc-driver-sqlite | 0.8.0 | sql-other | 用于 SQLite 的 ADBC 驱动程序 |
其他数据源
使用 pip install "pandas[hdf5, parquet, feather, spss, excel]"
可以安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
PyTables | 3.8.0 | hdf5 | 基于 HDF5 的读取 / 写入 |
blosc | 1.21.3 | hdf5 | HDF5 的压缩;仅在 conda 上可用 |
zlib | hdf5 | HDF5 的压缩 | |
fastparquet | 2022.12.0 | Parquet 的读取 / 写入(pyarrow 是默认的) | |
pyarrow | 10.0.1 | parquet, feather | Parquet、ORC 和 feather 的读取 / 写入 |
pyreadstat | 1.2.0 | spss | SPSS 文件(.sav)读取 |
odfpy | 1.4.1 | excel | 读取 / 写入开放文档格式(.odf、.ods、.odt) |
警告
- 如果您想要使用
read_orc()
,强烈建议使用 conda 安装 pyarrow。如果使用 pypi 安装了 pyarrow,可能会导致read_orc()
失败,并且read_orc()
不兼容 Windows 操作系统。
云端数据访问
使用 pip install "pandas[fss, aws, gcp]"
可以安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
fsspec | 2022.11.0 | fss, gcp, aws | 处理除了简单本地和 HTTP 之外的文件(s3fs、gcsfs 的必需依赖) |
gcsfs | 2022.11.0 | gcp | 谷歌云存储访问 |
pandas-gbq | 0.19.0 | gcp | 谷歌大查询访问 |
s3fs | 2022.11.0 | aws | 亚马逊 S3 访问 |
剪贴板
使用 pip install "pandas[clipboard]"
可以安装。
依赖 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
PyQt4/PyQt5 | 5.15.9 | clipboard | 剪贴板 I/O |
qtpy | 2.3.0 | clipboard | 剪贴板 I/O |
注意
根据操作系统的不同,可能需要安装系统级包。在 Linux 上,要使剪贴板正常工作,您的系统必须安装其中一个 CLI 工具 xclip
或 xsel
。
压缩
使用 pip install "pandas[compression]"
可以安装。
依赖 | 最低版本 | pip 额外 | 注意 |
---|---|---|---|
Zstandard | 0.19.0 | 压缩 | Zstandard 压缩 |
联盟标准
可以使用 pip install "pandas[consortium-standard]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注意 |
---|---|---|---|
dataframe-api-compat | 0.1.7 | 联盟标准 | 基于 pandas 的联盟标准兼容实现 |
性能依赖(推荐)
注:
强烈建议您安装这些库,因为它们可以提供速度改进,特别是在处理大型数据集时。
可以使用 pip install "pandas[performance]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注意 |
---|---|---|---|
numexpr | 2.8.4 | 性能 | 通过使用多核心以及智能分块和缓存来加速某些数值操作,从而实现大幅加速 |
bottleneck | 1.3.6 | 性能 | 通过使用专门的 cython 程序例程来加速某些类型的 nan ,从而实现大幅加速 |
numba | 0.56.4 | 性能 | 对于接受 engine="numba" 的操作,使用将 Python 函数转换为优化的机器代码的 JIT 编译器执行引擎。 |
可视化
可以使用 pip install "pandas[plot, output-formatting]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注意 |
---|---|---|---|
matplotlib | 3.6.3 | 绘图 | 绘图库 |
Jinja2 | 3.1.2 | 输出格式化 | 使用 DataFrame.style 进行条件格式化 |
tabulate | 0.9.0 | 输出格式化 | 以 Markdown 友好格式打印(参见 tabulate) |
计算
可以使用 pip install "pandas[computation]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注意 |
---|---|---|---|
SciPy | 1.10.0 | 计算 | 各种统计函数 |
xarray | 2022.12.0 | 计算 | 用于 N 维数据的类似 pandas 的 API |
Excel 文件
可以使用 pip install "pandas[excel]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注意 |
---|---|---|---|
xlrd | 2.0.1 | excel | 读取 Excel |
xlsxwriter | 3.0.5 | excel | 写入 Excel |
openpyxl | 3.1.0 | excel | 用于 xlsx 文件的读取/写入 |
pyxlsb | 1.0.10 | excel | 读取 xlsb 文件 |
python-calamine | 0.1.7 | excel | 读取 xls/xlsx/xlsb/ods 文件 |
HTML
可以使用 pip install "pandas[html]"
进行安装。
依赖 | 最低版本 | pip 额外 | 注意 |
---|---|---|---|
BeautifulSoup4 | 4.11.2 | html | 用于 read_html 的 HTML 解析器 |
html5lib | 1.1 | html | 用于 read_html 的 HTML 解析器 |
lxml | 4.9.2 | html | 用于 read_html 的 HTML 解析器 |
使用以下组合之一的库来使用顶层 read_html()
函数:
-
只有 lxml,但是请参阅 HTML 表解析,了解为什么您可能 不 应采用这种方法。
警告
-
如果您安装了BeautifulSoup4,您必须安装lxml或者html5lib,或者两者都安装。只安装BeautifulSoup4 将无法使
read_html()
工作。 -
非常鼓励阅读 HTML 表解析陷阱。它解释了围绕上述三个库的安装和使用的问题。
XML
可通过 pip install "pandas[xml]"
安装。
依赖项 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
lxml | 4.9.2 | xml | read_xml 的 XML 解析器和 to_xml 的树构建器 |
SQL 数据库
使用 pip install "pandas[postgresql, mysql, sql-other]"
可以安装传统驱动程序。
依赖项 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
SQLAlchemy | 2.0.0 | postgresql, mysql, sql-other | 除 SQLite 外的其他数据库的 SQL 支持 |
psycopg2 | 2.9.6 | postgresql | sqlalchemy 的 PostgreSQL 引擎 |
pymysql | 1.0.2 | mysql | sqlalchemy 的 MySQL 引擎 |
adbc-driver-postgresql | 0.8.0 | postgresql | PostgreSQL 的 ADBC 驱动程序 |
adbc-driver-sqlite | 0.8.0 | sql-other | SQLite 的 ADBC 驱动程序 |
其他数据源
使用 pip install "pandas[hdf5, parquet, feather, spss, excel]"
可以安装。
依赖项 | 最低版本 | pip 额外 | 注释 |
---|---|---|---|
PyTables | 3.8.0 | hdf5 | 基于 HDF5 的读取/写入 |
blosc | 1.21.3 | hdf5 | HDF5 的压缩;只在 conda 上可用 |
zlib | hdf5 | HDF5 的压缩 | |
fastparquet | 2022.12.0 | Parquet 读取/写入(pyarrow 是默认的) | |
pyarrow | 10.0.1 | parquet, feather | Parquet、ORC 和 feather 读取/写入 |
pyreadstat | 1.2.0 | spss | SPSS 文件(.sav)读取 |
odfpy | 1.4.1 | excel | Open document format(.odf, .ods, .odt)读取/写入 |
警告
- 如果你想要使用
read_orc()
,强烈建议使用 conda 安装 pyarrow。如果从 pypi 安装了 pyarrow,read_orc()
可能会失败,并且read_orc()
不兼容 Windows 操作系统。
访问云端数据
使用pip install "pandas[fss, aws, gcp]"
进行安装。
依赖 | 最低版本 | pip 额外 | 备注 |
---|---|---|---|
fsspec | 2022.11.0 | fss, gcp, aws | 处理除简单本地和 HTTP 之外的文件(s3fs、gcsfs 的必需依赖)。 |
gcsfs | 2022.11.0 | gcp | 谷歌云存储访问 |
pandas-gbq | 0.19.0 | gcp | 谷歌大查询访问 |
s3fs | 2022.11.0 | aws | 亚马逊 S3 访问 |
剪贴板
使用pip install "pandas[clipboard]"
进行安装。
依赖 | 最低版本 | pip 额外 | 备注 |
---|---|---|---|
PyQt4/PyQt5 | 5.15.9 | clipboard | 剪贴板 I/O |
qtpy | 2.3.0 | clipboard | 剪贴板 I/O |
注意
根据操作系统的不同,可能需要安装系统级软件包。在 Linux 上,剪贴板要操作,系统上必须安装xclip
或xsel
中的一个 CLI 工具。
压缩
使用pip install "pandas[compression]"
进行安装。
依赖 | 最低版本 | pip 额外 | 备注 |
---|---|---|---|
Zstandard | 0.19.0 | compression | Zstandard 压缩 |
联盟标准
使用pip install "pandas[consortium-standard]"
进行安装。
依赖 | 最低版本 | pip 额外 | 备注 |
---|---|---|---|
dataframe-api-compat | 0.1.7 | consortium-standard | 基于 pandas 的符合联盟标准的实现 |
包概述
pandas 是一个Python包,提供快速、灵活和表达性强的数据结构,旨在使处理“关系”或“标记”数据变得简单和直观。它旨在成为在 Python 中进行实际、现实世界数据分析的基本高级构建块。此外,它还有更广泛的目标,即成为任何语言中最强大和灵活的开源数据分析/操作工具。它已经在这个目标的道路上取得了很大进展。
pandas 非常适合许多不同类型的数据:
- 具有异构类型列的表格数据,如 SQL 表或 Excel 电子表格
- 有序和无序(不一定是固定频率)的时间序列数据
- 具有行和列标签的任意矩阵数据(同质或异质类型)
- 任何其他形式的观测/统计数据集。数据不需要被标记,也可以放入 pandas 数据结构中。
pandas 的两个主要数据结构,Series
(1 维)和DataFrame
(2 维),处理金融、统计学、社会科学和许多工程领域的绝大多数典型用例。对于 R 用户,DataFrame
提供了 R 的data.frame
提供的一切,以及更多。pandas 建立在NumPy之上,旨在与许多其他第三方库在科学计算环境中很好地集成。
以下是 pandas 擅长的一些事情:
- 处理浮点和非浮点数据中的缺失数据(表示为 NaN)非常容易
- 大小可变性:可以从 DataFrame 和更高维对象中插入和删除列
- 自动和显式的数据对齐:对象可以显式地与一组标签对齐,或者用户可以简单地忽略标签,让
Series
、DataFrame
等在计算中自动为您对齐数据- 强大、灵活的分组功能,可以对数据集执行分割-应用-合并操作,用于聚合和转换数据
- 使将其他 Python 和 NumPy 数据结构中的不规则、具有不同索引的数据轻松转换为 DataFrame 对象变得容易
- 对大型数据集进行智能基于标签的切片、高级索引和子集操作
- 直观的合并和连接数据集
- 灵活的数据集重塑和透视
- 轴的分层标签(每个刻度可能有多个标签)
- 用于从平面文件(CSV 和分隔符)、Excel 文件、数据库加载数据以及从超快速HDF5 格式保存/加载数据的强大 IO 工具
- 时间序列特定功能:日期范围生成和频率转换,滑动窗口统计,日期移动和滞后。
这些原则中的许多都是为了解决在使用其他语言/科学研究环境时经常遇到的缺点。对于数据科学家来说,处理数据通常分为多个阶段:整理和清理数据,分析/建模,然后将分析结果组织成适合绘图或表格显示的形式。pandas 是所有这些任务的理想工具。
其他一些注意事项
- pandas 速度快。许多底层算法部分在Cython代码中已经得到了大量调整。但是,与其他任何事物一样,一般化通常会牺牲性能。因此,如果您专注于应用程序的某一特性,您可能能够创建一个更快的专业工具。
- pandas 是statsmodels的依赖项,使其成为 Python 统计计算生态系统中的重要部分。
- pandas 已在金融应用程序中广泛使用。
数据结构
维度 | 名称 | 描述 |
---|---|---|
1 | Series | 一维标记同构类型数组 |
2 | DataFrame | 通用的二维标记、可变大小的表格结构,列的类型可能异构 |
为什么需要多个数据结构?
最好将 pandas 数据结构视为适用于低维数据的灵活容器。例如,DataFrame 是 Series 的容器,而 Series 是标量的容器。我们希望能够以类似字典的方式向这些容器中插入和删除对象。
另外,我们希望常见 API 函数的默认行为能够考虑到时间序列和横截面数据集的典型方向。当使用 N 维数组(ndarrays)存储二维和三维数据时,用户在编写函数时需要考虑数据集的方向;轴被认为是更或多或少等效的(除非 C- 或 Fortran-连续性对性能很重要)。在 pandas 中,轴旨在为数据提供更多的语义含义;即,对于特定的数据集,很可能有一种“正确”的方式来定位数据。因此,目标是减少编写下游函数中的数据转换所需的心理努力。
例如,对于表格数据(DataFrame),更有语义的方法是考虑索引(行)和列,而不是轴 0 和轴 1。因此,通过 DataFrame 的列进行迭代将产生更可读的代码:
for col in df.columns:
series = df[col]
# do something with series
数据的可变性和复制
所有 pandas 数据结构都是值可变的(它们包含的值可以被改变),但不总是大小可变的。Series 的长度不能改变,但是,例如,可以在 DataFrame 中插入列。然而,绝大多数方法会产生新对象并保持输入数据不变。通常情况下,我们喜欢偏向不可变性。
获取支持
pandas 问题和想法的第一站是GitHub Issue Tracker。如果您有一般问题,pandas 社区专家可以通过Stack Overflow回答。
社区
今天,pandas 得到全球志同道合的个人社区的积极支持,他们贡献了宝贵的时间和精力,帮助使开源 pandas 成为可能。感谢所有贡献者。
如果您有兴趣贡献,请访问贡献指南。
pandas 是NumFOCUS赞助的项目。这将有助于确保 pandas 作为世界一流开源项目的成功,并使捐赠给该项目成为可能。
项目治理
pandas 项目自 2008 年成立以来一直在非正式使用的治理流程在项目治理文件中得到了正式化。这些文件澄清了决策的方式以及我们社区的各个元素如何互动,包括开源协作开发与可能由营利性或非营利性实体资助的工作之间的关系。
Wes McKinney 是终身仁慈独裁者(BDFL)。
开发团队
核心团队成员列表和更详细信息可在pandas 网站上找到。
机构合作伙伴
关于当前机构合作伙伴的信息可在pandas 网站页面上找到。
许可证
BSD 3-Clause License
Copyright (c) 2008-2011, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
All rights reserved.
Copyright (c) 2011-2023, Open source contributors.
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.
数据结构
维度 | 名称 | 描述 |
---|---|---|
1 | Series | 1D 标记同质类型数组 |
2 | DataFrame | 通用的二维标记,大小可变的表格结构,列可能具有异构类型 |
为什么需要多个数据结构?
最好将 pandas 数据结构视为低维数据的灵活容器。例如,DataFrame 是 Series 的容器,而 Series 是标量的容器。我们希望能够以类似字典的方式插入和删除这些容器中的对象。
此外,我们希望常见 API 函数有合理的默认行为,考虑到时间序列和横截面数据集的典型方向。当使用 N 维数组(ndarrays)存储 2 维和 3 维数据时,用户需要考虑数据集的方向来编写函数;轴被认为是更或多或少等价的(除非 C 或 Fortran 连续性对性能有影响)。在 pandas 中,轴旨在为数据提供更多语义意义;即,对于特定数据集,可能有一种“正确”的方式来定位数据。因此,目标是减少编写下游函数中数据转换所需的心智努力量。
例如,对于表格数据(DataFrame),更有语义的方式是考虑索引(行)和列,而不是轴 0 和轴 1。因此,通过 DataFrame 的列进行迭代会导致更易读的代码:
for col in df.columns:
series = df[col]
# do something with series
为什么会有多个数据结构?
最好的方式是将 pandas 数据结构视为低维数据的灵活容器。例如,DataFrame 是 Series 的容器,而 Series 是标量的容器。我们希望能够以类似字典的方式向这些容器中插入和移除对象。
此外,我们希望常见 API 函数有合理的默认行为,考虑到时间序列和横截面数据集的典型方向。当使用 N 维数组(ndarrays)存储 2 维和 3 维数据时,用户需要考虑数据集的方向来编写函数;轴被认为是更或多或少等价的(除非 C 或 Fortran 连续性对性能有影响)。在 pandas 中,轴旨在为数据提供更多语义意义;即,对于特定数据集,可能有一种“正确”的方式来定位数据。因此,目标是减少编写下游函数中数据转换所需的心智努力量。
例如,对于表格数据(DataFrame),更有语义的方式是考虑索引(行)和列,而不是轴 0 和轴 1。因此,通过 DataFrame 的列进行迭代会导致更易读的代码:
for col in df.columns:
series = df[col]
# do something with series
可变性和数据的复制
所有的 pandas 数据结构都是值可变的(它们包含的值可以被改变),但并非总是大小可变的。Series 的长度不能被改变,但是,例如,可以在 DataFrame 中插入列。然而,绝大多数方法会产生新对象,并保持输入数据不变。一般来说,我们喜欢偏向不可变性,在合适的情况下。
获取支持
pandas 的问题和想法的第一站是GitHub Issue Tracker。如果您有一般问题,pandas 社区专家可以通过Stack Overflow回答。
社区
今天,pandas 受到全球志同道合的个人社区的积极支持,他们贡献了宝贵的时间和精力来帮助使开源 pandas 成为可能。感谢我们所有的贡献者。
如果您有兴趣贡献,请访问贡献指南。
pandas 是一个NumFOCUS赞助的项目。这将有助于确保 pandas 作为一个世界一流的开源项目的成功,并使捐赠给该项目成为可能。
项目治理
pandas 项目自 2008 年成立以来一直使用的治理流程已在项目治理文件中正式规范化。这些文件澄清了如何做出决策以及我们社区各个元素之间的互动方式,包括开源协作开发与可能由营利性或非营利性实体资助的工作之间的关系。
Wes McKinney 是终身仁慈独裁者(BDFL)。
开发团队
核心团队成员列表和更详细的信息可以在pandas 网站上找到。
机构合作伙伴
当前机构合作伙伴的信息可以在pandas 网站页面上找到。
许可证
BSD 3-Clause License
Copyright (c) 2008-2011, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
All rights reserved.
Copyright (c) 2011-2023, Open source contributors.
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.
入门教程
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/index.html
- pandas 处理什么类型的数据?
-
如何读取和写入表格数据?
-
如何选择
DataFrame
的子集? -
如何在 pandas 中创建图表?
-
如何从现有列派生新列
-
如何计算摘要统计信息
-
如何重新设计表格布局
-
如何合并来自多个表的数据
-
如何轻松处理时间序列数据
-
如何操作文本数据
pandas 处理什么类型的数据?
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/01_table_oriented.html
-
我想开始使用 pandas
In [1]: import pandas as pd
要加载 pandas 包并开始使用它,请导入该包。 社区约定的 pandas 别名是
pd
,因此假定将 pandas 加载为pd
是所有 pandas 文档的标准做法。
pandas 数据表表示
-
我想存储泰坦尼克号的乘客数据。 对于许多乘客,我知道姓名(字符),年龄(整数)和性别(男/女)数据。
In [2]: df = pd.DataFrame( ...: { ...: "Name": [ ...: "Braund, Mr. Owen Harris", ...: "Allen, Mr. William Henry", ...: "Bonnell, Miss. Elizabeth", ...: ], ...: "Age": [22, 35, 58], ...: "Sex": ["male", "male", "female"], ...: } ...: ) ...: In [3]: df Out[3]: Name Age Sex 0 Braund, Mr. Owen Harris 22 male 1 Allen, Mr. William Henry 35 male 2 Bonnell, Miss. Elizabeth 58 female
要手动将数据存储在表中,请创建一个
DataFrame
。 使用 Python 字典列表时,字典键将用作列标题,每个列表中的值将用作DataFrame
的列。
一个DataFrame
是一个可以在列中存储不同类型数据(包括字符、整数、浮点值、分类数据等)的二维数据结构。 它类似于电子表格、SQL 表或 R 中的data.frame
。
-
表格有 3 列,每列都有一个列标签。 列标签分别是
Name
、Age
和Sex
。 -
列
Name
由文本数据组成,每个值都是一个字符串,列Age
是数字,列Sex
是文本数据。
在电子表格软件中,我们的数据的表格表示看起来会非常相似:
DataFrame
中的每一列都是一个Series
-
我只对在
Age
列中的数据感兴趣In [4]: df["Age"] Out[4]: 0 22 1 35 2 58 Name: Age, dtype: int64
当选择 pandas
DataFrame
的单个列时,结果是一个 pandasSeries
。 要选择列,请在方括号[]
之间使用列标签。
注意
如果您熟悉 Python dictionaries,选择单个列与基于键选择字典值非常相似。
你也可以从头开始创建一个Series
:
In [5]: ages = pd.Series([22, 35, 58], name="Age")
In [6]: ages
Out[6]:
0 22
1 35
2 58
Name: Age, dtype: int64
pandas 的Series
没有列标签,因为它只是DataFrame
的单列。 Series 确实有行标签。
对 DataFrame 或 Series 执行某些操作
-
我想知道乘客的最大年龄
我们可以通过选择
Age
列并应用max()
在DataFrame
上执行此操作:In [7]: df["Age"].max() Out[7]: 58
或者到
Series
:In [8]: ages.max() Out[8]: 58
正如 max()
方法所示,您可以使用 DataFrame
或 Series
执行 操作。pandas 提供了许多功能,每个功能都是您可以应用于 DataFrame
或 Series
的 方法。由于方法是函数,不要忘记使用括号 ()
。
-
我对我的数据表的数值数据进行一些基本统计感兴趣
In [9]: df.describe() Out[9]: Age count 3.000000 mean 38.333333 std 18.230012 min 22.000000 25% 28.500000 50% 35.000000 75% 46.500000 max 58.000000
describe()
方法提供了对DataFrame
中数值数据的快速概述。由于Name
和Sex
列是文本数据,默认情况下不会被describe()
方法考虑在内。
许多 pandas 操作会返回一个 DataFrame
或一个 Series
。describe()
方法就是一个返回 pandas Series
或 pandas DataFrame
的 pandas 操作的示例。
转至用户指南
在用户指南的关于 使用 describe 进行汇总的部分中查看更多选项
注意
这只是一个起点。与电子表格软件类似,pandas 将数据表示为具有列和行的表格。除了表示外,还有您在电子表格软件中进行的数据操作和计算,pandas 也支持。继续阅读下一篇教程,开始使用!
记住
-
导入包,即
import pandas as pd
-
数据表以 pandas 的
DataFrame
形式存储 -
DataFrame
中的每一列都是一个Series
-
您可以通过将方法应用于
DataFrame
或Series
来执行操作
转至用户指南
关于 DataFrame
和 Series
的更详细解释在数据结构简介中提供。
pandas 数据表表示
-
我想存储 Titanic 的乘客数据。对于许多乘客,我知道他们的姓名(字符)、年龄(整数)和性别(男性/女性)数据。
In [2]: df = pd.DataFrame( ...: { ...: "Name": [ ...: "Braund, Mr. Owen Harris", ...: "Allen, Mr. William Henry", ...: "Bonnell, Miss. Elizabeth", ...: ], ...: "Age": [22, 35, 58], ...: "Sex": ["male", "male", "female"], ...: } ...: ) ...: In [3]: df Out[3]: Name Age Sex 0 Braund, Mr. Owen Harris 22 male 1 Allen, Mr. William Henry 35 male 2 Bonnell, Miss. Elizabeth 58 female
要手动存储数据到表格中,创建一个
DataFrame
。当使用 Python 字典的列表时,字典的键将被用作列标题,每个列表中的值将作为DataFrame
的列。
DataFrame
是一种二维数据结构,可以在列中存储不同类型的数据(包括字符、整数、浮点值、分类数据等)。它类似于电子表格、SQL 表或 R 中的 data.frame
。
-
表格有 3 列,每列都有一个列标签。列标签分别是
Name
、Age
和Sex
。 -
列
Name
包含文本数据,每个值为字符串,列Age
是数字,列Sex
是文本数据。
在电子表格软件中,我们的数据的表格表示看起来会非常相似:
每个DataFrame
中的列都是一个Series
-
我只对
Age
列中的数据感兴趣In [4]: df["Age"] Out[4]: 0 22 1 35 2 58 Name: Age, dtype: int64
当选择 pandas
DataFrame
的单个列时,结果是一个 pandasSeries
。要选择列,请在方括号[]
之间使用列标签。
注意
如果你熟悉 Python dictionaries,选择单个列与基于键选择字典值非常相似。
你也可以从头开始创建一个Series
:
In [5]: ages = pd.Series([22, 35, 58], name="Age")
In [6]: ages
Out[6]:
0 22
1 35
2 58
Name: Age, dtype: int64
一个 pandas Series
没有列标签,因为它只是一个DataFrame
的单列。一个 Series 有行标签。
对DataFrame
或Series
执行一些操作
-
我想知道乘客的最大年龄
我们可以通过选择
Age
列并应用max()
来对DataFrame
进行操作:In [7]: df["Age"].max() Out[7]: 58
或对
Series
进行操作:In [8]: ages.max() Out[8]: 58
正如max()
方法所示,你可以对DataFrame
或Series
执行操作。pandas 提供了许多功能,每个功能都是可以应用于DataFrame
或Series
的方法。由于方法是函数,请不要忘记使用括号()
。
-
我对我的数据表的数值数据感兴趣的一些基本统计信息
In [9]: df.describe() Out[9]: Age count 3.000000 mean 38.333333 std 18.230012 min 22.000000 25% 28.500000 50% 35.000000 75% 46.500000 max 58.000000
describe()
方法提供了DataFrame
中数值数据的快速概述。由于Name
和Sex
列是文本数据,默认情况下不会被describe()
方法考虑在内。
许多 pandas 操作会返回一个DataFrame
或一个Series
。describe()
方法就是一个返回 pandas Series
或 pandas DataFrame
的 pandas 操作的示例。
转到用户指南
在用户��南的关于使用 describe 进行聚合部分查看更多关于describe
的选项
注意
这只是一个起点。与电子表格软件类似,pandas 将数据表示为具有列和行的表格。除了表示,pandas 还支持电子表格软件中的数据操作和计算。继续阅读下一个教程以开始!
记住
-
导入包,即
import pandas as pd
-
数据表以 pandas
DataFrame
的形式存储 -
每个
DataFrame
中的列都是一个Series
-
你可以通过将方法应用于
DataFrame
或Series
来完成任务。
前往用户指南
关于 DataFrame
和 Series
的更详细解释可在数据结构介绍中找到。
如何读取和写入表格数据?
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/02_read_write.html
-
我想分析泰坦尼克号乘客数据,该数据以 CSV 文件的形式提供。
In [2]: titanic = pd.read_csv("data/titanic.csv")
pandas 提供
read_csv()
函数,将存储为 csv 文件的数据读取到 pandas 的DataFrame
中。pandas 支持许多不同的文件格式或数据源(csv、excel、sql、json、parquet 等),每个都带有前缀read_*
。
在读取数据后,务必始终检查数据。显示DataFrame
时,默认会显示前后 5 行:
In [3]: titanic
Out[3]:
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
1 2 1 1 ... 71.2833 C85 C
2 3 1 3 ... 7.9250 NaN S
3 4 1 1 ... 53.1000 C123 S
4 5 0 3 ... 8.0500 NaN S
.. ... ... ... ... ... ... ...
886 887 0 2 ... 13.0000 NaN S
887 888 1 1 ... 30.0000 B42 S
888 889 0 3 ... 23.4500 NaN S
889 890 1 1 ... 30.0000 C148 C
890 891 0 3 ... 7.7500 NaN Q
[891 rows x 12 columns]
-
我想看一下 pandas DataFrame 的前 8 行。
In [4]: titanic.head(8) Out[4]: PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S 5 6 0 3 ... 8.4583 NaN Q 6 7 0 1 ... 51.8625 E46 S 7 8 0 3 ... 21.0750 NaN S [8 rows x 12 columns]
要查看
DataFrame
的前 N 行,请使用head()
方法,并将所需的行数(在本例中为 8)作为参数。
注意
对最后 N 行感兴趣吗?pandas 还提供了tail()
方法。例如,titanic.tail(10)
将返回 DataFrame 的最后 10 行。
通过请求 pandas 的dtypes
属性,可以检查 pandas 如何解释每列的数据类型:
In [5]: titanic.dtypes
Out[5]:
PassengerId int64
Survived int64
Pclass int64
Name object
Sex object
Age float64
SibSp int64
Parch int64
Ticket object
Fare float64
Cabin object
Embarked object
dtype: object
对于每列,列出了使用的数据类型。此DataFrame
中的数据类型为整数(int64
)、浮点数(float64
)和字符串(object
)。
注意
请求dtypes
时,不使用括号!dtypes
是DataFrame
和Series
的属性。DataFrame
或Series
的属性不需要括号。属性表示DataFrame
/Series
的特征,而方法(需要括号)在第一个教程中介绍了DataFrame
/Series
的操作。
-
我的同事请求将泰坦尼克号数据作为电子表格。
In [6]: titanic.to_excel("titanic.xlsx", sheet_name="passengers", index=False)
而
read_*
函数用于将数据读取到 pandas 中,to_*
方法用于存储数据。to_excel()
方法将数据存储为 excel 文件。在此示例中,sheet_name
命名为passengers,而不是默认的Sheet1。通过设置index=False
,行索引标签不会保存在电子表格中。
等效的读取函数read_excel()
将重新加载数据到DataFrame
中:
In [7]: titanic = pd.read_excel("titanic.xlsx", sheet_name="passengers")
In [8]: titanic.head()
Out[8]:
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
1 2 1 1 ... 71.2833 C85 C
2 3 1 3 ... 7.9250 NaN S
3 4 1 1 ... 53.1000 C123 S
4 5 0 3 ... 8.0500 NaN S
[5 rows x 12 columns]
-
我对
DataFrame
的技术摘要感兴趣In [9]: titanic.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 891 entries, 0 to 890 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 PassengerId 891 non-null int64 1 Survived 891 non-null int64 2 Pclass 891 non-null int64 3 Name 891 non-null object 4 Sex 891 non-null object 5 Age 714 non-null float64 6 SibSp 891 non-null int64 7 Parch 891 non-null int64 8 Ticket 891 non-null object 9 Fare 891 non-null float64 10 Cabin 204 non-null object 11 Embarked 889 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 83.7+ KB
info()
方法提供有关DataFrame
的技术信息,让我们更详细地解释输出:-
确实是一个
DataFrame
。 -
有 891 个条目,即 891 行。
-
每行都有一个行标签(又称
index
),其值范围从 0 到 890。 -
表格有 12 列。大多数列在每一行都有一个值(所有 891 个值都是
non-null
)。一些列确实有缺失值,少于 891 个non-null
值。 -
列
Name
、Sex
、Cabin
和Embarked
由文本数据(字符串,又称object
)组成。其他列是数值数据,其中一些是整数(又称integer
),另一些是实数(又称float
)。 -
不同列中的数据类型(字符、整数等)通过列出
dtypes
进行总结。 -
提供了用于保存 DataFrame 的大致 RAM 使用量。
-
记住
-
通过
read_*
函数支持从许多不同文件格式或数据源将数据导入 pandas。 -
通过不同的
to_*
方法提供了将数据导出到 pandas 的功能。 -
head
/tail
/info
方法和dtypes
属性对于初步检查很方便。
到用户指南
有关从 pandas 到输入和输出的完整概述,请参阅有关读取器和写入器函数的用户指南部分。
如何选择 DataFrame 的子集?
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/03_subset_data.html
如何从DataFrame
中选择特定列?
-
我对泰坦尼克号乘客的年龄感兴趣。
In [4]: ages = titanic["Age"] In [5]: ages.head() Out[5]: 0 22.0 1 38.0 2 26.0 3 35.0 4 35.0 Name: Age, dtype: float64
要选择单个列,请使用方括号
[]
与感兴趣的列名。
每个DataFrame
中的列都是一个Series
。当选择单个列时,返回的对象是一个 pandas Series
。我们可以通过检查输出的类型来验证这一点:
In [6]: type(titanic["Age"])
Out[6]: pandas.core.series.Series
并查看输出的shape
:
In [7]: titanic["Age"].shape
Out[7]: (891,)
DataFrame.shape
是一个属性(记住读写教程中不要对属性使用括号), 用于包含行数和列数的 pandas Series
和 DataFrame
:(nrows, ncolumns)。pandas Series 是一维的,只返回行数。
-
我对泰坦尼克号乘客的年龄和性别感兴趣。
In [8]: age_sex = titanic[["Age", "Sex"]] In [9]: age_sex.head() Out[9]: Age Sex 0 22.0 male 1 38.0 female 2 26.0 female 3 35.0 female 4 35.0 male
要选择多个列,请在选择括号
[]
内使用列名列表。
注意
内部方括号定义了一个Python 列表,其中包含列名,而外部方括号用于从 pandas DataFrame
中选择数据,就像在前面的示例中看到的那样。
返回的数据类型是一个 pandas DataFrame:
In [10]: type(titanic[["Age", "Sex"]])
Out[10]: pandas.core.frame.DataFrame
In [11]: titanic[["Age", "Sex"]].shape
Out[11]: (891, 2)
选择返回了一个具有 891 行和 2 列的DataFrame
。记住,DataFrame
是二维的,具有行和列两个维度。
转到用户指南
有关索引的基本信息,请参阅用户指南中关于索引和选择数据的部分。
如何从DataFrame
中过滤特���行?
-
我对年龄大于 35 岁的乘客感兴趣。
In [12]: above_35 = titanic[titanic["Age"] > 35] In [13]: above_35.head() Out[13]: PassengerId Survived Pclass ... Fare Cabin Embarked 1 2 1 1 ... 71.2833 C85 C 6 7 0 1 ... 51.8625 E46 S 11 12 1 1 ... 26.5500 C103 S 13 14 0 3 ... 31.2750 NaN S 15 16 1 2 ... 16.0000 NaN S [5 rows x 12 columns]
要基于条件表达式选择行,请在选择括号
[]
内使用条件。
选择括号内的条件titanic["Age"] > 35
检查Age
列的值是否大于 35 的行:
In [14]: titanic["Age"] > 35
Out[14]:
0 False
1 True
2 False
3 False
4 False
...
886 False
887 False
888 False
889 False
890 False
Name: Age, Length: 891, dtype: bool
条件表达式的输出(>
,但也可以是 ==
,!=
,<
,<=
,...)实际上是一个具有与原始DataFrame
相同行数的布尔值(True
或 False
)的 pandas Series
。这样的布尔值Series
可以通过将其放在选择括号[]
之间来过滤DataFrame
。只有值为True
的行才会被选择。
我们之前知道原始泰坦尼克号DataFrame
由 891 行组成。让我们通过检查结果DataFrame
above_35
的shape
属性来查看满足条件的行数:
In [15]: above_35.shape
Out[15]: (217, 12)
-
我对泰坦尼克号的 2 和 3 舱位乘客感兴趣。
In [16]: class_23 = titanic[titanic["Pclass"].isin([2, 3])] In [17]: class_23.head() Out[17]: PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 2 3 1 3 ... 7.9250 NaN S 4 5 0 3 ... 8.0500 NaN S 5 6 0 3 ... 8.4583 NaN Q 7 8 0 3 ... 21.0750 NaN S [5 rows x 12 columns]
与条件表达式类似,
isin()
条件函数会对提供的列表中的每一行返回True
。要基于这样的函数过滤行,请在选择括号[]
内使用条件函数。在这种情况下,选择括号内的条件titanic["Pclass"].isin([2, 3])
检查Pclass
列为 2 或 3 的行。
上述操作等同于按照舱位为 2 或 3 的行进行筛选,并使用|
(或)运算符将两个语句组合在一起:
In [18]: class_23 = titanic[(titanic["Pclass"] == 2) | (titanic["Pclass"] == 3)]
In [19]: class_23.head()
Out[19]:
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
2 3 1 3 ... 7.9250 NaN S
4 5 0 3 ... 8.0500 NaN S
5 6 0 3 ... 8.4583 NaN Q
7 8 0 3 ... 21.0750 NaN S
[5 rows x 12 columns]
注意
在组合多个条件语句时,每个条件必须用括号()
括起来。此外,不能使用or
/and
,而是需要使用or
运算符|
和and
运算符&
。
到用户指南
请查看用户指南中关于布尔索引或 isin 函数的专门部分。
-
我想处理已知年龄的乘客数据。
In [20]: age_no_na = titanic[titanic["Age"].notna()] In [21]: age_no_na.head() Out[21]: PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S [5 rows x 12 columns]
notna()
条件函数会对值不是Null
值的每一行返回True
。因此,可以将其与选择括号[]
结合使用来过滤数据表。
你可能会想知道实际发生了什么变化,因为前 5 行仍然是相同的值。验证的一种方法是检查形状是否发生了变化:
In [22]: age_no_na.shape
Out[22]: (714, 12)
到用户指南
有关缺失值的更多专用函数,请参阅用户指南中关于处理缺失数据的部分。
如何从DataFrame
中选择特定的行和列?
-
我对 35 岁以上的乘客姓名感兴趣。
In [23]: adult_names = titanic.loc[titanic["Age"] > 35, "Name"] In [24]: adult_names.head() Out[24]: 1 Cumings, Mrs. John Bradley (Florence Briggs Th... 6 McCarthy, Mr. Timothy J 11 Bonnell, Miss. Elizabeth 13 Andersson, Mr. Anders Johan 15 Hewlett, Mrs. (Mary D Kingcome) Name: Name, dtype: object
在这种情况下,一次性对行和列进行子集操作,仅使用选择括号
[]
已经不够了。在选择括号[]
前面需要使用loc
/iloc
运算符。使用loc
/iloc
时,逗号前面的部分是你想要的行,逗号后面的部分是你想要选择的列。
当使用列名、行标签或条件表达式时,请在选择括号[]
前面使用loc
运算符。对于逗号前后的部分,可以使用单个标签、标签列表、标签切片、条件表达式或冒号。使用冒号指定你想选择所有行或列。
-
我对第 10 到 25 行和第 3 到 5 列感兴趣。
In [25]: titanic.iloc[9:25, 2:5] Out[25]: Pclass Name Sex 9 2 Nasser, Mrs. Nicholas (Adele Achem) female 10 3 Sandstrom, Miss. Marguerite Rut female 11 1 Bonnell, Miss. Elizabeth female 12 3 Saundercock, Mr. William Henry male 13 3 Andersson, Mr. Anders Johan male .. ... ... ... 20 2 Fynney, Mr. Joseph J male 21 2 Beesley, Mr. Lawrence male 22 3 McGowan, Miss. Anna "Annie" female 23 1 Sloper, Mr. William Thompson male 24 3 Palsson, Miss. Torborg Danira female [16 rows x 3 columns]
再次,一次性对行和列的子集进行选择,仅使用选择括号
[]
已经不再足够。当特别关注表中位置的某些行和/或列时,请在选择括号[]
前使用iloc
运算符。
使用loc
或iloc
选择特定行和/或列时,可以为所选数据分配新值。例如,为第四列的前 3 个元素分配名称anonymous
:
In [26]: titanic.iloc[0:3, 3] = "anonymous"
In [27]: titanic.head()
Out[27]:
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
1 2 1 1 ... 71.2833 C85 C
2 3 1 3 ... 7.9250 NaN S
3 4 1 1 ... 53.1000 C123 S
4 5 0 3 ... 8.0500 NaN S
[5 rows x 12 columns]
转到用户指南
查看用户指南关于索引选择的不同选择部分,以更深入了解loc
和iloc
的用法。
记住
-
在选择数据子集时,使用方括号
[]
。 -
在这些括号内,您可以使用单个列/行标签、列/行标签列表、标签切片、条件表达式或冒号。
-
使用
loc
选择特定行和/或列时,请使用行和列名称。 -
使用
iloc
选择特定行和/或列时,请使用表中的位置。 -
您可以基于
loc
/iloc
分配新值给选择。
转到用户指南
用户指南页面提供了有关索引和选择数据的完整概述。
如何从DataFrame
中选择特定列?
-
我对泰坦尼克号乘客的年龄感兴趣。
In [4]: ages = titanic["Age"] In [5]: ages.head() Out[5]: 0 22.0 1 38.0 2 26.0 3 35.0 4 35.0 Name: Age, dtype: float64
要选择单列,使用方括号
[]
和感兴趣的列的列名。
DataFrame
中的每一列都是一个Series
。当选择单列时,返回的对象是一个 pandas Series
。我们可以通过检查输出的类型来验证这一点:
In [6]: type(titanic["Age"])
Out[6]: pandas.core.series.Series
并查看输出的shape
:
In [7]: titanic["Age"].shape
Out[7]: (891,)
DataFrame.shape
是一个属性(请记住读写教程,对于属性不要使用括号),包含行数和列数:(nrows, ncolumns)。pandas Series 是 1 维的,只返回行数。
-
我对泰坦尼克号乘客的年龄和性别感兴趣。
In [8]: age_sex = titanic[["Age", "Sex"]] In [9]: age_sex.head() Out[9]: Age Sex 0 22.0 male 1 38.0 female 2 26.0 female 3 35.0 female 4 35.0 male
要选择多列,使用选择括号
[]
内的列名列表。
注意
内部方括号定义了一个Python 列表,其中包含列名,而外部方括号用于从 pandas DataFrame
中选择数据,就像在前面的示例中看到的那样。
返回的数据类型是一个 pandas DataFrame:
In [10]: type(titanic[["Age", "Sex"]])
Out[10]: pandas.core.frame.DataFrame
In [11]: titanic[["Age", "Sex"]].shape
Out[11]: (891, 2)
选择返回了一个具有 891 行和 2 列的DataFrame
。请记住,DataFrame
是二维的,具有行和列两个维度。
转到用户指南
有关索引的基本信息,请参阅用户指南中关于索引和选择数据的部分。
如何从DataFrame
中筛选特定行?
-
我对 35 岁以上的乘客感兴趣。
In [12]: above_35 = titanic[titanic["Age"] > 35] In [13]: above_35.head() Out[13]: PassengerId Survived Pclass ... Fare Cabin Embarked 1 2 1 1 ... 71.2833 C85 C 6 7 0 1 ... 51.8625 E46 S 11 12 1 1 ... 26.5500 C103 S 13 14 0 3 ... 31.2750 NaN S 15 16 1 2 ... 16.0000 NaN S [5 rows x 12 columns]
要基于条件表达式选择行,请在选择括号
[]
内使用条件。
选择括号内条件titanic["Age"] > 35
检查Age
列数值大于 35 的行:
In [14]: titanic["Age"] > 35
Out[14]:
0 False
1 True
2 False
3 False
4 False
...
886 False
887 False
888 False
889 False
890 False
Name: Age, Length: 891, dtype: bool
条件表达式的输出(>
, 也可以是 ==
, !=
, <
, <=
,…)实际上是一个布尔值的 pandas Series
(True
或 False
)与原始 DataFrame
行数相同。这样的布尔值 Series
可以用于通过将其放在选择括号[]
之间来过滤 DataFrame
。只有值为True
的行将被选中。
我们之前知道原始泰坦尼克DataFrame
由 891 行组成。让我们通过检查above_35
的结果DataFrame
的shape
属性来查看满足条件的行数:
In [15]: above_35.shape
Out[15]: (217, 12)
-
我对泰坦尼克号 2 和 3 舱位的乘客感兴趣。
In [16]: class_23 = titanic[titanic["Pclass"].isin([2, 3])] In [17]: class_23.head() Out[17]: PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 2 3 1 3 ... 7.9250 NaN S 4 5 0 3 ... 8.0500 NaN S 5 6 0 3 ... 8.4583 NaN Q 7 8 0 3 ... 21.0750 NaN S [5 rows x 12 columns]
与条件表达式类似,
isin()
条件函数对于每一行数值在提供的列表中时返回True
。要基于此类函数过滤行,请在选择括号[]
内使用条件函数。在这种情况下,选择括号内条件titanic["Pclass"].isin([2, 3])
检查Pclass
列数值为 2 或 3 的行。
上述等同于按照舱位为 2 或 3 的行进行过滤,并使用|
(或)运算符将两个语句组合:
In [18]: class_23 = titanic[(titanic["Pclass"] == 2) | (titanic["Pclass"] == 3)]
In [19]: class_23.head()
Out[19]:
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
2 3 1 3 ... 7.9250 NaN S
4 5 0 3 ... 8.0500 NaN S
5 6 0 3 ... 8.4583 NaN Q
7 8 0 3 ... 21.0750 NaN S
[5 rows x 12 columns]
注意
当组合多个条件语句时,每个条件必须用括号()
括起来。此外,不能使用 or
/and
,而是需要使用 or
运算符 |
和 and
运算符 &
。
转到用户指南
请查看用户指南中关于布尔索引或 isin 函数的专门部分。
-
我想处理已知年龄的乘客数据。
In [20]: age_no_na = titanic[titanic["Age"].notna()] In [21]: age_no_na.head() Out[21]: PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S [5 rows x 12 columns]
notna()
条件函数对于每一行数值不是Null
值时返回True
。因此,可以与选择括号[]
结合使用来过滤数据表。
你可能想知道实际发生了什么变化,因为前 5 行仍然是相同的值。验证的一种方法是检查形状是否发生了变化:
In [22]: age_no_na.shape
Out[22]: (714, 12)
转到用户指南
想要了解更多关于处理缺失值的专用功能,请查看用户指南中关于处理缺失数据的部分。
如何从DataFrame
中选择特定的行和列?
-
我对年龄大于 35 岁的乘客的姓名感兴趣。
In [23]: adult_names = titanic.loc[titanic["Age"] > 35, "Name"] In [24]: adult_names.head() Out[24]: 1 Cumings, Mrs. John Bradley (Florence Briggs Th... 6 McCarthy, Mr. Timothy J 11 Bonnell, Miss. Elizabeth 13 Andersson, Mr. Anders Johan 15 Hewlett, Mrs. (Mary D Kingcome) Name: Name, dtype: object
在这种情况下,一次性选择行和列的子集,并且仅使用选择括号
[]
已经不再足够。需要在选择括号[]
前使用loc
/iloc
运算符。在使用loc
/iloc
时,逗号前面的部分是您想要的行,逗号后面的部分是您要选择的列。
当使用列名称、行标签或条件表达式时,请在选择括号[]
前使用loc
运算符。对于逗号前后的部分,您可以使用单个标签、标签列表、标签切片、条件表达式或冒号。使用冒号指定您要选择所有行或列。
-
我对第 10 到 25 行和第 3 到 5 列感兴趣。
In [25]: titanic.iloc[9:25, 2:5] Out[25]: Pclass Name Sex 9 2 Nasser, Mrs. Nicholas (Adele Achem) female 10 3 Sandstrom, Miss. Marguerite Rut female 11 1 Bonnell, Miss. Elizabeth female 12 3 Saundercock, Mr. William Henry male 13 3 Andersson, Mr. Anders Johan male .. ... ... ... 20 2 Fynney, Mr. Joseph J male 21 2 Beesley, Mr. Lawrence male 22 3 McGowan, Miss. Anna "Annie" female 23 1 Sloper, Mr. William Thompson male 24 3 Palsson, Miss. Torborg Danira female [16 rows x 3 columns]
再次,一次性选择行和列的子集,并且仅使用选择括号
[]
已经不再足够。当特别关注表中位置的某些行和/或列时,请在选择括号[]
前使用iloc
运算符。
在使用loc
或iloc
选择特定行和/或列时,可以为所选数据分配新值。例如,要将名称anonymous
分配给第四列的前 3 个元素:
In [26]: titanic.iloc[0:3, 3] = "anonymous"
In [27]: titanic.head()
Out[27]:
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
1 2 1 1 ... 71.2833 C85 C
2 3 1 3 ... 7.9250 NaN S
3 4 1 1 ... 53.1000 C123 S
4 5 0 3 ... 8.0500 NaN S
[5 rows x 12 columns]
前往用户指南
查看用户指南中关于索引的不同选择以获取有关loc
和iloc
用法的更多见解。
记住
-
在选择数据子集时,使用方括号
[]
。 -
在这些括号内,您可以使用单个列/行标签、列/行标签列表、标签切片、条件表达式或冒号。
-
使用
loc
选择特定行和/或列时,请使用行和列名称。 -
使用
iloc
选择特定行和/或列时,请使用表中的位置。 -
您可以根据
loc
/iloc
的选择分配新值。
前往用户指南
用户指南页面提供了有关索引和选择数据的完整概述。
如何在 pandas 中创建图表?
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/04_plotting.html
In [1]: import pandas as pd
In [2]: import matplotlib.pyplot as plt
本教程使用的数据:
-
空气质量数据
本教程使用关于(NO_2)的空气质量数据,由OpenAQ提供,并使用py-openaq包。
air_quality_no2.csv
数据集提供了分别来自巴黎、安特卫普和伦敦的测量站FR04014、BETR801和London Westminster的(NO_2)值。In [3]: air_quality = pd.read_csv("data/air_quality_no2.csv", index_col=0, parse_dates=True) In [4]: air_quality.head() Out[4]: station_antwerp station_paris station_london datetime 2019-05-07 02:00:00 NaN NaN 23.0 2019-05-07 03:00:00 50.5 25.0 19.0 2019-05-07 04:00:00 45.0 27.7 19.0 2019-05-07 05:00:00 NaN 50.4 16.0 2019-05-07 06:00:00 NaN 61.9 NaN
注意
使用
read_csv
函数的index_col
和parse_dates
参数,将第一(0)列定义为生成的DataFrame
的索引,并将列中的日期转换为Timestamp
对象。 -
我想快速地对数据进行可视化检查。
In [5]: air_quality.plot() Out[5]: <Axes: xlabel='datetime'> In [6]: plt.show()
使用
DataFrame
,pandas 默认为具有数值数据的每列创建一条线图。 -
我只想绘制数据表中来自巴黎的列。
In [7]: air_quality["station_paris"].plot() Out[7]: <Axes: xlabel='datetime'> In [8]: plt.show()
要绘制特定列,请结合子集数据教程中的选择方法和
plot()
方法。因此,plot()
方法适用于Series
和DataFrame
。 -
我想要直观比较伦敦和巴黎测得的(NO_2)值。
In [9]: air_quality.plot.scatter(x="station_london", y="station_paris", alpha=0.5) Out[9]: <Axes: xlabel='station_london', ylabel='station_paris'> In [10]: plt.show()
在使用plot
函数时,除了默认的line
图之外,还有许多可用于绘制数据的替代方法。让我们使用一些标准 Python 来了解可用绘图方法:
In [11]: [
....: method_name
....: for method_name in dir(air_quality.plot)
....: if not method_name.startswith("_")
....: ]
....:
Out[11]:
['area',
'bar',
'barh',
'box',
'density',
'hexbin',
'hist',
'kde',
'line',
'pie',
'scatter']
注意
在许多开发环境以及 IPython 和 Jupyter Notebook 中,使用 TAB 键可以获得可用方法的概览,例如 air_quality.plot.
+ TAB。
其中一个选项是DataFrame.plot.box()
,它指的是箱线图。box
方法适用于空气质量示例数据:
In [12]: air_quality.plot.box()
Out[12]: <Axes: >
In [13]: plt.show()
用户指南
除了默认的折线图之外,有关支持的绘图样式的介绍,请参阅用户指南中关于支持的绘图样式的部分。
-
我想将每列分别放在单独的子图中。
In [14]: axs = air_quality.plot.area(figsize=(12, 4), subplots=True) In [15]: plt.show()
通过
plot
函数的subplots
参数支持为每个数据列创建单独的子图。值得回顾每个 pandas 绘图函数中提供的内置选项。
到用户指南
更多格式选项在用户指南的绘图格式化部分有详细说明。
-
我想进一步自定义、扩展或保存生成的图。
In [16]: fig, axs = plt.subplots(figsize=(12, 4)) In [17]: air_quality.plot.area(ax=axs) Out[17]: <Axes: xlabel='datetime'> In [18]: axs.set_ylabel("NO$_2$ concentration") Out[18]: Text(0, 0.5, 'NO$_2$ concentration') In [19]: fig.savefig("no2_concentrations.png") In [20]: plt.show()
pandas 创建的每个绘图对象都是一个Matplotlib对象。由于 Matplotlib 提供了大量自定义绘图的选项,使 pandas 和 Matplotlib 之间的链接明确,可以将 Matplotlib 的所有功能应用于绘图。这种策略在前面的示例中应用:
fig, axs = plt.subplots(figsize=(12, 4)) # Create an empty Matplotlib Figure and Axes
air_quality.plot.area(ax=axs) # Use pandas to put the area plot on the prepared Figure/Axes
axs.set_ylabel("NO$_2$ concentration") # Do any Matplotlib customization you like
fig.savefig("no2_concentrations.png") # Save the Figure/Axes using the existing Matplotlib method.
plt.show() # Display the plot
记住
-
.plot.*
方法适用于 Series 和 DataFrames。 -
默认情况下,每列都被绘制为不同的元素(线条、箱线图等)。
-
由 pandas 创建的任何绘图都是一个 Matplotlib 对象。
到用户指南
在可视化页面中提供了 pandas 绘图的完整概述。
如何从现有列派生新列
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/05_add_columns.html
-
我想要以 mg/m(³)表示伦敦站的(NO_2)浓度。
(如果我们假设温度为 25 摄氏度,压力为 1013 百帕,转换系数为 1.882)
In [4]: air_quality["london_mg_per_cubic"] = air_quality["station_london"] * 1.882 In [5]: air_quality.head() Out[5]: station_antwerp ... london_mg_per_cubic datetime ... 2019-05-07 02:00:00 NaN ... 43.286 2019-05-07 03:00:00 50.5 ... 35.758 2019-05-07 04:00:00 45.0 ... 35.758 2019-05-07 05:00:00 NaN ... 30.112 2019-05-07 06:00:00 NaN ... NaN [5 rows x 4 columns]
要创建新列,请使用
[]
括号,新列名称位于赋值的左侧。
注意
值的计算是逐元素进行的。这意味着给定列中的所有值一次性乘以值 1.882。您不需要使用循环迭代每一行!
-
我想检查巴黎与安特卫普的比值,并将结果保存在一个新列中。
In [6]: air_quality["ratio_paris_antwerp"] = ( ...: air_quality["station_paris"] / air_quality["station_antwerp"] ...: ) ...: In [7]: air_quality.head() Out[7]: station_antwerp ... ratio_paris_antwerp datetime ... 2019-05-07 02:00:00 NaN ... NaN 2019-05-07 03:00:00 50.5 ... 0.495050 2019-05-07 04:00:00 45.0 ... 0.615556 2019-05-07 05:00:00 NaN ... NaN 2019-05-07 06:00:00 NaN ... NaN [5 rows x 5 columns]
计算再次逐元素进行,因此
/
适用于每行的值。
还有其他数学运算符(+
,-
,*
,/
,…)或逻辑运算符(<
,>
,==
,…)逐元素工作。后者在子集数据教程中已经用于使用条件表达式过滤表的行。
如果您需要更高级的逻辑,可以通过apply()
使用任意 Python 代码。
-
我想将数据列重命名为由OpenAQ使用的相应站点标识符。
In [8]: air_quality_renamed = air_quality.rename( ...: columns={ ...: "station_antwerp": "BETR801", ...: "station_paris": "FR04014", ...: "station_london": "London Westminster", ...: } ...: ) ...:
In [9]: air_quality_renamed.head() Out[9]: BETR801 FR04014 ... london_mg_per_cubic ratio_paris_antwerp datetime ... 2019-05-07 02:00:00 NaN NaN ... 43.286 NaN 2019-05-07 03:00:00 50.5 25.0 ... 35.758 0.495050 2019-05-07 04:00:00 45.0 27.7 ... 35.758 0.615556 2019-05-07 05:00:00 NaN 50.4 ... 30.112 NaN 2019-05-07 06:00:00 NaN 61.9 ... NaN NaN [5 rows x 5 columns]
rename()
函数可用于行标签和列标签。提供一个字典,键是当前名称,值是要更新的新名称以更新相应的名称。
映射不应仅限于固定名称,还可以是映射函数。例如,也可以使用函数将列名称转换为小写字母:
In [10]: air_quality_renamed = air_quality_renamed.rename(columns=str.lower)
In [11]: air_quality_renamed.head()
Out[11]:
betr801 fr04014 ... london_mg_per_cubic ratio_paris_antwerp
datetime ...
2019-05-07 02:00:00 NaN NaN ... 43.286 NaN
2019-05-07 03:00:00 50.5 25.0 ... 35.758 0.495050
2019-05-07 04:00:00 45.0 27.7 ... 35.758 0.615556
2019-05-07 05:00:00 NaN 50.4 ... 30.112 NaN
2019-05-07 06:00:00 NaN 61.9 ... NaN NaN
[5 rows x 5 columns]
到用户指南
有关列或行标签重命名的详细信息,请参阅用户指南中的重命名标签部分。
记住
-
通过在
[]
之间的新列名称处将输出分配给 DataFrame 来创建新列。 -
运算是逐元素进行的,不需要循环遍历行。
-
使用字典或函数与
rename
一起重命名行标签或列名称。
到用户指南
用户指南中有一个独立的部分介绍了列的添加和删除。
如何计算摘要统计信息
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/06_calculate_statistics.html
聚合统计
-
泰坦尼克号乘客的平均年龄是多少?
In [4]: titanic["Age"].mean() Out[4]: 29.69911764705882
可用不同统计数据并可以应用于具有数值数据的列。一般情况下,操作将排除缺失数据,并默认跨行操作。
-
泰坦尼克号乘客的中位年龄和票价是多少?
In [5]: titanic[["Age", "Fare"]].median() Out[5]: Age 28.0000 Fare 14.4542 dtype: float64
对于
DataFrame
的多列(选择两列返回一个DataFrame
,参见子集数据教程)应用的统计数据针对每个数字列进行计算。
聚合统计信息可以同时计算多列。记得从第一个教程中的describe
函数吗?
In [6]: titanic[["Age", "Fare"]].describe()
Out[6]:
Age Fare
count 714.000000 891.000000
mean 29.699118 32.204208
std 14.526497 49.693429
min 0.420000 0.000000
25% 20.125000 7.910400
50% 28.000000 14.454200
75% 38.000000 31.000000
max 80.000000 512.329200
与预定义的统计数据不同,可以使用DataFrame.agg()
方法定义给定列的特定组合的聚合统计信息:
In [7]: titanic.agg(
...: {
...: "Age": ["min", "max", "median", "skew"],
...: "Fare": ["min", "max", "median", "mean"],
...: }
...: )
...:
Out[7]:
Age Fare
min 0.420000 0.000000
max 80.000000 512.329200
median 28.000000 14.454200
skew 0.389108 NaN
mean NaN 32.204208
到用户指南
在用户指南中提供了关于描述性统计的详细信息,参见描述性统计一节。
按类别分组的聚合统计
-
泰坦尼克号乘客的男性与女性的平均年龄是多少?
In [8]: titanic[["Sex", "Age"]].groupby("Sex").mean() Out[8]: Age Sex female 27.915709 male 30.726645
由于我们的兴趣是每个性别的平均年龄,首先对这两列进行子选择:
titanic[["Sex", "Age"]]
。然后,在Sex
列上应用groupby()
方法,以每个类别生成一个分组。计算并返回每个性别的平均年龄。
计算给定统计数据(例如mean
年龄)对于列中的每个类别(例如Sex
列中的男性/女性)是一种常见模式。groupby
方法用于支持这种类型的操作。这适用于更通用的split-apply-combine
模式:
-
拆分数据成组
-
对每个组独立应用一个函数
-
合并结果到一个数据结构中
在 pandas 中,应用和合并步骤通常一起完成。
在前面的示例中,我们明确选择了前两列。如果没有,将通过传递numeric_only=True
将mean
方法应用于包含数字列的每一列:
In [9]: titanic.groupby("Sex").mean(numeric_only=True)
Out[9]:
PassengerId Survived Pclass ... SibSp Parch Fare
Sex ...
female 431.028662 0.742038 2.159236 ... 0.694268 0.649682 44.479818
male 454.147314 0.188908 2.389948 ... 0.429809 0.235702 25.523893
[2 rows x 7 columns]
获取Pclass
的平均值并没有太多意义。如果我们只对每个性别的平均年龄感兴趣,那么在分组数据上也支持对列的选择(如通常所见的方括号[]
):
In [10]: titanic.groupby("Sex")["Age"].mean()
Out[10]:
Sex
female 27.915709
male 30.726645
Name: Age, dtype: float64
注意
Pclass
列包含数字数据,但实际上代表着 3 个类别(或因子),分别标有 '1'、'2' 和 '3' 的标签。对这些数据进行统计计算并不太合理。因此,pandas 提供了 Categorical
数据类型来处理这种类型的数据。更多信息请参阅用户指南中的分类数据部分。
-
在性别和舱位等级组合中,票价的平均值是多少?
In [11]: titanic.groupby(["Sex", "Pclass"])["Fare"].mean() Out[11]: Sex Pclass female 1 106.125798 2 21.970121 3 16.118810 male 1 67.226127 2 19.741782 3 12.661633 Name: Fare, dtype: float64
可以同时通过多列进行分组。将列名作为列表提供给
groupby()
方法。
转至用户指南
关于分组-应用-合并方法的全面描述可在用户指南的分组操作部分找到。
按类别计算记录数
-
在每个舱位等级中的乘客数量是多少?
In [12]: titanic["Pclass"].value_counts() Out[12]: Pclass 3 491 1 216 2 184 Name: count, dtype: int64
value_counts()
方法计算列中每个类别的记录数。
该函数是一个快捷方式,因为实际上是一个组合了分组操作和对每个组内记录数进行计数的操作:
In [13]: titanic.groupby("Pclass")["Pclass"].count()
Out[13]:
Pclass
1 216
2 184
3 491
Name: Pclass, dtype: int64
注意
size
和 count
都可以与 groupby
结合使用。而 size
包括 NaN
值并且仅提供行数(表的大小),count
则排除缺失值。在 value_counts
方法中,使用 dropna
参数来包含或排除 NaN
值。
转至用户指南
用户指南有一个专门介绍 value_counts
的部分,请参阅离散化页面。
记住
-
聚合统计可以在整个列或行上计算。
-
groupby
提供了 分组-应用-合并 模式的强大功能。 -
value_counts
是一个方便的快捷方式,用于计算变量的每个类别中的条目数。
转至用户指南
关于分组-应用-合并方法的全面描述可在用户指南的分组操作页面找到。
聚合统计
-
泰坦尼克号乘客的平均年龄是多少?
In [4]: titanic["Age"].mean() Out[4]: 29.69911764705882
不同的统计数据可用,并且可以应用于具有数字数据的列。操作通常会排除缺失数据,并默认跨行操作。
-
泰坦尼克号乘客的中位年龄和票价是多少?
In [5]: titanic[["Age", "Fare"]].median() Out[5]: Age 28.0000 Fare 14.4542 dtype: float64
对
DataFrame
的多列(选择两列返回一个DataFrame
,参见子集数据教程)应用的统计量是针对每个数值列进行计算的。
聚合统计可以同时针对多列进行计算。还记得第一个教程中的describe
函数吗?
In [6]: titanic[["Age", "Fare"]].describe()
Out[6]:
Age Fare
count 714.000000 891.000000
mean 29.699118 32.204208
std 14.526497 49.693429
min 0.420000 0.000000
25% 20.125000 7.910400
50% 28.000000 14.454200
75% 38.000000 31.000000
max 80.000000 512.329200
可以使用DataFrame.agg()
方法定义给定列的特定聚合统计量组合,而不是预定义的统计量:
In [7]: titanic.agg(
...: {
...: "Age": ["min", "max", "median", "skew"],
...: "Fare": ["min", "max", "median", "mean"],
...: }
...: )
...:
Out[7]:
Age Fare
min 0.420000 0.000000
max 80.000000 512.329200
median 28.000000 14.454200
skew 0.389108 NaN
mean NaN 32.204208
转到用户指南
关于描述性统计的详细信息,请参阅用户指南中的描述性统计部分。
按类别分组的聚合统计
-
泰坦尼克号男性与女性乘客的平均年龄分别是多少?
In [8]: titanic[["Sex", "Age"]].groupby("Sex").mean() Out[8]: Age Sex female 27.915709 male 30.726645
由于我们感兴趣的是每个性别的平均年龄,首先对这两列进行了子选择:
titanic[["Sex", "Age"]]
。然后,应用groupby()
方法在Sex
列上进行分组,以每个类别创建一个组。计算并返回每个性别的平均年龄。
对于某一列中的每个类别(例如Sex
列中的男性/女性)计算给定统计量(例如mean
年龄)是一种常见模式。groupby
方法用于支持此类操作。这符合更一般的split-apply-combine
模式:
-
将数据分割成组
-
对每个分组独立应用一个函数
-
将结果合并成数据结构
在 pandas 中,应用和合并步骤通常一起完成。
在前面的示例中,我们首先明确选择了 2 列。如果没有,则通过传递numeric_only=True
将mean
方法应用于包含数值列的每列:
In [9]: titanic.groupby("Sex").mean(numeric_only=True)
Out[9]:
PassengerId Survived Pclass ... SibSp Parch Fare
Sex ...
female 431.028662 0.742038 2.159236 ... 0.694268 0.649682 44.479818
male 454.147314 0.188908 2.389948 ... 0.429809 0.235702 25.523893
[2 rows x 7 columns]
获取Pclass
的平均值并没有太多意义。如果我们只对每个性别的平均年龄感兴趣,那么在分组数据上也支持对列(如常规的方括号[]
)进行选择:
In [10]: titanic.groupby("Sex")["Age"].mean()
Out[10]:
Sex
female 27.915709
male 30.726645
Name: Age, dtype: float64
注意
Pclass
列包含数值数据,但实际上表示 3 个类别(或因子),分别具有标签‘1’、‘2’和‘3’。对这些进行统计没有太多意义。因此,pandas 提供了Categorical
数据类型来处理这种类型的数据。更多信息请参阅用户指南中的分类数据部分。
-
每个性别和舱位等级组合的平均票价是多少?
In [11]: titanic.groupby(["Sex", "Pclass"])["Fare"].mean() Out[11]: Sex Pclass female 1 106.125798 2 21.970121 3 16.118810 male 1 67.226127 2 19.741782 3 12.661633 Name: Fare, dtype: float64
分组可以同时按多个列进行。将列名作为列表提供给
groupby()
方法。
用户指南
关于分组操作的分割-应用-组合方法的完整描述,请参阅用户指南中的分组操作部分。
按类别计算记录数
-
每个客舱等级的乘客数量是多少?
In [12]: titanic["Pclass"].value_counts() Out[12]: Pclass 3 491 1 216 2 184 Name: count, dtype: int64
value_counts()
方法计算列中每个类别的记录数。
该函数是一个快捷方式,实际上是一个组合操作,结合了每个组内记录数的分组操作:
In [13]: titanic.groupby("Pclass")["Pclass"].count()
Out[13]:
Pclass
1 216
2 184
3 491
Name: Pclass, dtype: int64
注意
size
和 count
都可以与 groupby
结合使用。而 size
包括 NaN
值并且仅提供行数(表的大小),count
排除缺失值。在 value_counts
方法中,使用 dropna
参数来包含或排除 NaN
值。
用户指南
用户指南有一个专门介绍value_counts
的部分,请参阅离散化页面。
记住
-
可以在整个列或行上计算聚合统计信息。
-
groupby
提供了分割-应用-组合模式的强大功能。 -
value_counts
是计算变量每个类别中条目数量的便捷快捷方式。
用户指南
关于分组操作的用户指南页面中提供了关于分割-应用-组合方法的完整描述。
如何重新排列表格布局
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/07_reshape_table_layout.html
排序表格行
-
我想根据乘客的年龄对泰坦尼克号数据进行排序。
In [6]: titanic.sort_values(by="Age").head() Out[6]: PassengerId Survived Pclass ... Fare Cabin Embarked 803 804 1 3 ... 8.5167 NaN C 755 756 1 2 ... 14.5000 NaN S 644 645 1 3 ... 19.2583 NaN C 469 470 1 3 ... 19.2583 NaN C 78 79 1 2 ... 29.0000 NaN S [5 rows x 12 columns]
-
我想根据舱位等级和年龄按降序对泰坦尼克号数据进行排序。
In [7]: titanic.sort_values(by=['Pclass', 'Age'], ascending=False).head() Out[7]: PassengerId Survived Pclass ... Fare Cabin Embarked 851 852 0 3 ... 7.7750 NaN S 116 117 0 3 ... 7.7500 NaN Q 280 281 0 3 ... 7.7500 NaN Q 483 484 1 3 ... 9.5875 NaN S 326 327 0 3 ... 6.2375 NaN S [5 rows x 12 columns]
使用
DataFrame.sort_values()
,表格中的行根据定义的列进行排序。索引将遵循行顺序。
用户指南
有关表格排序的更多详细信息,请参阅用户指南中关于数据排序的部分。
从长表格格式到宽表格格式
让我们使用空气质量数据集的一个小子集。我们关注(NO_2)数据,并仅使用每个位置的前两个测量值(即每个组���头部)。数据子集将被称为no2_subset
。
# filter for no2 data only
In [8]: no2 = air_quality[air_quality["parameter"] == "no2"]
# use 2 measurements (head) for each location (groupby)
In [9]: no2_subset = no2.sort_index().groupby(["location"]).head(2)
In [10]: no2_subset
Out[10]:
city country ... value unit
date.utc ...
2019-04-09 01:00:00+00:00 Antwerpen BE ... 22.5 µg/m³
2019-04-09 01:00:00+00:00 Paris FR ... 24.4 µg/m³
2019-04-09 02:00:00+00:00 London GB ... 67.0 µg/m³
2019-04-09 02:00:00+00:00 Antwerpen BE ... 53.5 µg/m³
2019-04-09 02:00:00+00:00 Paris FR ... 27.4 µg/m³
2019-04-09 03:00:00+00:00 London GB ... 67.0 µg/m³
[6 rows x 6 columns]
-
我想要三个站点的值分别作为相邻的列。
In [11]: no2_subset.pivot(columns="location", values="value") Out[11]: location BETR801 FR04014 London Westminster date.utc 2019-04-09 01:00:00+00:00 22.5 24.4 NaN 2019-04-09 02:00:00+00:00 53.5 27.4 67.0 2019-04-09 03:00:00+00:00 NaN NaN 67.0
pivot()
函数纯粹是对数据的重新排列:每个索引/列组合需要一个单一值。
由于 pandas 支持多列绘图(参见绘图教程),因此从长表格格式转换为宽表格格式可以同时绘制不同时间序列的图表:
In [12]: no2.head()
Out[12]:
city country location parameter value unit
date.utc
2019-06-21 00:00:00+00:00 Paris FR FR04014 no2 20.0 µg/m³
2019-06-20 23:00:00+00:00 Paris FR FR04014 no2 21.8 µg/m³
2019-06-20 22:00:00+00:00 Paris FR FR04014 no2 26.5 µg/m³
2019-06-20 21:00:00+00:00 Paris FR FR04014 no2 24.9 µg/m³
2019-06-20 20:00:00+00:00 Paris FR FR04014 no2 21.4 µg/m³
In [13]: no2.pivot(columns="location", values="value").plot()
Out[13]: <Axes: xlabel='date.utc'>
注意
当未定义index
参数时,将使用现有索引(行标签)。
用户指南
有关pivot()
的更多信息,请参阅用户指南中关于数据透视表对象的部分。
透视表
-
我想要表格形式中每个站点的(NO_2)和(PM_{2.5})的平均浓度。
In [14]: air_quality.pivot_table( ....: values="value", index="location", columns="parameter", aggfunc="mean" ....: ) ....: Out[14]: parameter no2 pm25 location BETR801 26.950920 23.169492 FR04014 29.374284 NaN London Westminster 29.740050 13.443568
在
pivot()
的情况下,数据只是重新排列。当需要聚合多个值(在这种特定情况下,不同时间步长上的值)时,可以使用pivot_table()
,提供一个聚合函数(例如均值)来组合这些值。
透视表是电子表格软件中一个众所周知的概念。当对每个变量的行/列边距(小计)感兴趣时,请将margins
参数设置为True
:
In [15]: air_quality.pivot_table(
....: values="value",
....: index="location",
....: columns="parameter",
....: aggfunc="mean",
....: margins=True,
....: )
....:
Out[15]:
parameter no2 pm25 All
location
BETR801 26.950920 23.169492 24.982353
FR04014 29.374284 NaN 29.374284
London Westminster 29.740050 13.443568 21.491708
All 29.430316 14.386849 24.222743
用户指南
有关pivot_table()
的更多信息,请参阅用户指南中关于数据透视表的部分。
注意
如果你在想,pivot_table()
确实直接与groupby()
相关联。可以通过在parameter
和location
上进行分组来得到相同的结果:
air_quality.groupby(["parameter", "location"])[["value"]].mean()
转至用户指南
从宽格式到长格式
从前一节创建的宽格式表重新开始,我们使用reset_index()
为DataFrame
添加新索引。
In [16]: no2_pivoted = no2.pivot(columns="location", values="value").reset_index()
In [17]: no2_pivoted.head()
Out[17]:
location date.utc BETR801 FR04014 London Westminster
0 2019-04-09 01:00:00+00:00 22.5 24.4 NaN
1 2019-04-09 02:00:00+00:00 53.5 27.4 67.0
2 2019-04-09 03:00:00+00:00 54.5 34.2 67.0
3 2019-04-09 04:00:00+00:00 34.5 48.5 41.0
4 2019-04-09 05:00:00+00:00 46.5 59.5 41.0
-
我想将所有空气质量(NO_2)测量值收集到单独的一列中(长格式)。
In [18]: no_2 = no2_pivoted.melt(id_vars="date.utc") In [19]: no_2.head() Out[19]: date.utc location value 0 2019-04-09 01:00:00+00:00 BETR801 22.5 1 2019-04-09 02:00:00+00:00 BETR801 53.5 2 2019-04-09 03:00:00+00:00 BETR801 54.5 3 2019-04-09 04:00:00+00:00 BETR801 34.5 4 2019-04-09 05:00:00+00:00 BETR801 46.5
在
DataFrame
上调用pandas.melt()
方法将数据表从宽格式转换为长格式。列标题变为新创建列中的变量名。
解决方案是如何应用pandas.melt()
的简短版本。该方法将所有未在id_vars
中提及的列融合成两列:一列是列标题名称,另一列是值本身。后一列默认名称为value
。
传递给pandas.melt()
的参数可以更详细地定义:
In [20]: no_2 = no2_pivoted.melt(
....: id_vars="date.utc",
....: value_vars=["BETR801", "FR04014", "London Westminster"],
....: value_name="NO_2",
....: var_name="id_location",
....: )
....:
In [21]: no_2.head()
Out[21]:
date.utc id_location NO_2
0 2019-04-09 01:00:00+00:00 BETR801 22.5
1 2019-04-09 02:00:00+00:00 BETR801 53.5
2 2019-04-09 03:00:00+00:00 BETR801 54.5
3 2019-04-09 04:00:00+00:00 BETR801 34.5
4 2019-04-09 05:00:00+00:00 BETR801 46.5
附加参数具有以下效果:
-
value_vars
定义要融合在一起的列 -
value_name
为值列提供自定义列名,而不是默认列名value
-
var_name
为收集列标题名称的列提供自定义列名。否则,它将采用索引名称或默认值variable
因此,参数value_name
和var_name
只是两个生成列的用户定义名称。要融合的列由id_vars
和value_vars
定义。
转至用户指南
使用pandas.melt()
将数据从宽格式转换为长格式在用户指南中有详细说明,参见融合重塑部分。
记住
-
支持按一个或多个列排序的
sort_values
。 -
pivot
函数纯粹是数据重构,pivot_table
支持聚合。 -
pivot
的反向操作(从长格式到宽格式)是melt
(从宽格式到长格式)。
转至用户指南
用户指南中关于重塑和数据透视的页面提供了完整的概述。
排序表行
-
我想根据乘客的年龄对泰坦尼克号数据进行排序。
In [6]: titanic.sort_values(by="Age").head() Out[6]: PassengerId Survived Pclass ... Fare Cabin Embarked 803 804 1 3 ... 8.5167 NaN C 755 756 1 2 ... 14.5000 NaN S 644 645 1 3 ... 19.2583 NaN C 469 470 1 3 ... 19.2583 NaN C 78 79 1 2 ... 29.0000 NaN S [5 rows x 12 columns]
-
我想根据船舱等级和年龄按降序对泰坦尼克号数据进行排序。
In [7]: titanic.sort_values(by=['Pclass', 'Age'], ascending=False).head() Out[7]: PassengerId Survived Pclass ... Fare Cabin Embarked 851 852 0 3 ... 7.7750 NaN S 116 117 0 3 ... 7.7500 NaN Q 280 281 0 3 ... 7.7500 NaN Q 483 484 1 3 ... 9.5875 NaN S 326 327 0 3 ... 6.2375 NaN S [5 rows x 12 columns]
使用
DataFrame.sort_values()
,表中的行将根据定义的列进行排序。索引将遵循行顺序。
转到用户指南
有关表格排序的更多详细信息,请参阅用户指南中关于数据排序的部分。
从长表格格式到宽表格格式
让我们使用空气质量数据集的一个小子集。我们关注(NO_2)数据,并且只使用每个位置的前两次测量(即每个组的头部)。数据子集将被称为no2_subset
。
# filter for no2 data only
In [8]: no2 = air_quality[air_quality["parameter"] == "no2"]
# use 2 measurements (head) for each location (groupby)
In [9]: no2_subset = no2.sort_index().groupby(["location"]).head(2)
In [10]: no2_subset
Out[10]:
city country ... value unit
date.utc ...
2019-04-09 01:00:00+00:00 Antwerpen BE ... 22.5 µg/m³
2019-04-09 01:00:00+00:00 Paris FR ... 24.4 µg/m³
2019-04-09 02:00:00+00:00 London GB ... 67.0 µg/m³
2019-04-09 02:00:00+00:00 Antwerpen BE ... 53.5 µg/m³
2019-04-09 02:00:00+00:00 Paris FR ... 27.4 µg/m³
2019-04-09 03:00:00+00:00 London GB ... 67.0 µg/m³
[6 rows x 6 columns]
-
我想要三个站点的值作为相邻的单独列��
In [11]: no2_subset.pivot(columns="location", values="value") Out[11]: location BETR801 FR04014 London Westminster date.utc 2019-04-09 01:00:00+00:00 22.5 24.4 NaN 2019-04-09 02:00:00+00:00 53.5 27.4 67.0 2019-04-09 03:00:00+00:00 NaN NaN 67.0
pivot()
函数纯粹是对数据的重塑:每个索引/列组合需要一个单一值。
由于 pandas 支持多列的绘图(请参阅绘图教程),因此从长表格格式转换为宽表格格式使得可以同时绘制不同时间序列:
In [12]: no2.head()
Out[12]:
city country location parameter value unit
date.utc
2019-06-21 00:00:00+00:00 Paris FR FR04014 no2 20.0 µg/m³
2019-06-20 23:00:00+00:00 Paris FR FR04014 no2 21.8 µg/m³
2019-06-20 22:00:00+00:00 Paris FR FR04014 no2 26.5 µg/m³
2019-06-20 21:00:00+00:00 Paris FR FR04014 no2 24.9 µg/m³
2019-06-20 20:00:00+00:00 Paris FR FR04014 no2 21.4 µg/m³
In [13]: no2.pivot(columns="location", values="value").plot()
Out[13]: <Axes: xlabel='date.utc'>
注意
当未定义index
参数时,将使用现有的索引(行标签)。
转到用户指南
有关pivot()
的更多信息,请参阅用户指南中关于数据透视表 DataFrame 对象的部分。
数据透视表
-
我想要每个站点中(NO_2)和(PM_{2.5})的平均浓度以表格形式呈现。
In [14]: air_quality.pivot_table( ....: values="value", index="location", columns="parameter", aggfunc="mean" ....: ) ....: Out[14]: parameter no2 pm25 location BETR801 26.950920 23.169492 FR04014 29.374284 NaN London Westminster 29.740050 13.443568
在
pivot()
的情况下,数据仅被重新排列。当需要聚合多个值(在这种特定情况下,不同时间步的值)时,可以使用pivot_table()
,提供一个聚合函数(例如平均值)来组合这些值。
数据透视表是电子表格软件中一个众所周知的概念。当对每个变量的行/列边距(小计)感兴趣时,请将margins
参数设置为True
:
In [15]: air_quality.pivot_table(
....: values="value",
....: index="location",
....: columns="parameter",
....: aggfunc="mean",
....: margins=True,
....: )
....:
Out[15]:
parameter no2 pm25 All
location
BETR801 26.950920 23.169492 24.982353
FR04014 29.374284 NaN 29.374284
London Westminster 29.740050 13.443568 21.491708
All 29.430316 14.386849 24.222743
转到用户指南
欲了解有关pivot_table()
的更多信息,请参阅用户指南中关于数据透视表的部分。
注意
如果你在想,pivot_table()
确实直接链接到groupby()
。相同的结果可以通过在parameter
和location
上进行分组来得到:
air_quality.groupby(["parameter", "location"])[["value"]].mean()
转到用户指南
宽到长格式
从前一节创建的宽格式表重新开始,我们使用reset_index()
为DataFrame
添加新索引。
In [16]: no2_pivoted = no2.pivot(columns="location", values="value").reset_index()
In [17]: no2_pivoted.head()
Out[17]:
location date.utc BETR801 FR04014 London Westminster
0 2019-04-09 01:00:00+00:00 22.5 24.4 NaN
1 2019-04-09 02:00:00+00:00 53.5 27.4 67.0
2 2019-04-09 03:00:00+00:00 54.5 34.2 67.0
3 2019-04-09 04:00:00+00:00 34.5 48.5 41.0
4 2019-04-09 05:00:00+00:00 46.5 59.5 41.0
-
我想将所有空气质量(\(NO_2\))测量值收集到单独的一列中(长格式)。
In [18]: no_2 = no2_pivoted.melt(id_vars="date.utc") In [19]: no_2.head() Out[19]: date.utc location value 0 2019-04-09 01:00:00+00:00 BETR801 22.5 1 2019-04-09 02:00:00+00:00 BETR801 53.5 2 2019-04-09 03:00:00+00:00 BETR801 54.5 3 2019-04-09 04:00:00+00:00 BETR801 34.5 4 2019-04-09 05:00:00+00:00 BETR801 46.5
pandas.melt()
方法在DataFrame
上将数据表从宽格式转换为长格式。列标题变为新创建列中的变量名称。
解决方案是如何应用pandas.melt()
的简短版本。该方法将未在id_vars
中提及的所有列融合到两列中:一列是列标题名称,另一列是值本身。后一列默认命名为value
。
传递给pandas.melt()
的参数可以更详细地定义:
In [20]: no_2 = no2_pivoted.melt(
....: id_vars="date.utc",
....: value_vars=["BETR801", "FR04014", "London Westminster"],
....: value_name="NO_2",
....: var_name="id_location",
....: )
....:
In [21]: no_2.head()
Out[21]:
date.utc id_location NO_2
0 2019-04-09 01:00:00+00:00 BETR801 22.5
1 2019-04-09 02:00:00+00:00 BETR801 53.5
2 2019-04-09 03:00:00+00:00 BETR801 54.5
3 2019-04-09 04:00:00+00:00 BETR801 34.5
4 2019-04-09 05:00:00+00:00 BETR801 46.5
附加参数具有以下效果:
-
value_vars
定义要融合在一起的列 -
value_name
为值列提供自定义列名,而不是默认列名value
-
var_name
为收集列标题名称的列提供自定义列名。否则,它将采用索引名称或默认的variable
因此,参数value_name
和var_name
只是生成的用户定义列 ocolumns 的名称。要融合的列由id_vars
和value_vars
定义。
转到用户指南
使用pandas.melt()
从宽格式转换为长格式在用户指南中有详细说明,参见通过 melt 进行重塑部分。
记住
-
通过
sort_values
支持按一个或多个列进行排序。 -
pivot
函数纯粹是数据重构,pivot_table
支持聚合。 -
pivot
的反向(从长到宽格式)是melt
(从宽到长格式)。
转到用户指南
完整概述可在关于重塑和旋转的用户指南页面上找到。
如何合并来自多个表的数据
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/08_combine_dataframes.html
连接对象
-
我想将(NO_2)和(PM_{25})的测量数据,两个结构相似的表,合并到一个表中。
In [8]: air_quality = pd.concat([air_quality_pm25, air_quality_no2], axis=0) In [9]: air_quality.head() Out[9]: date.utc location parameter value 0 2019-06-18 06:00:00+00:00 BETR801 pm25 18.0 1 2019-06-17 08:00:00+00:00 BETR801 pm25 6.5 2 2019-06-17 07:00:00+00:00 BETR801 pm25 18.5 3 2019-06-17 06:00:00+00:00 BETR801 pm25 16.0 4 2019-06-17 05:00:00+00:00 BETR801 pm25 7.5
concat()
函数执行多个表沿一个轴(行或列)的连接操作。
默认情况下,沿轴 0 进行连接,因此结果表合并了输入表的行。让我们检查原始表和连接表的形状以验证操作:
In [10]: print('Shape of the ``air_quality_pm25`` table: ', air_quality_pm25.shape)
Shape of the ``air_quality_pm25`` table: (1110, 4)
In [11]: print('Shape of the ``air_quality_no2`` table: ', air_quality_no2.shape)
Shape of the ``air_quality_no2`` table: (2068, 4)
In [12]: print('Shape of the resulting ``air_quality`` table: ', air_quality.shape)
Shape of the resulting ``air_quality`` table: (3178, 4)
因此,结果表有 3178 行= 1110 + 2068 行。
注意
axis参数将返回可以沿着轴应用的多个 pandas 方法。DataFrame
有两个对应的轴:第一个沿着行垂直向下运行(轴 0),第二个沿着列水平运行(轴 1)。大多数操作(如连接或汇总统计)默认跨行(轴 0),但也可以跨列应用。
根据日期时间信息对表进行排序也说明了两个表的组合,parameter
列定义了表的来源(来自air_quality_no2
表的no2
或来自air_quality_pm25
表的pm25
):
In [13]: air_quality = air_quality.sort_values("date.utc")
In [14]: air_quality.head()
Out[14]:
date.utc location parameter value
2067 2019-05-07 01:00:00+00:00 London Westminster no2 23.0
1003 2019-05-07 01:00:00+00:00 FR04014 no2 25.0
100 2019-05-07 01:00:00+00:00 BETR801 pm25 12.5
1098 2019-05-07 01:00:00+00:00 BETR801 no2 50.5
1109 2019-05-07 01:00:00+00:00 London Westminster pm25 8.0
在这个具体的例子中,数据提供的parameter
列确保可以识别原始表中的每个表。这并不总是这样。concat
函数提供了一个方便的解决方案,使用keys
参数添加一个额外的(分层)行索引。例如:
In [15]: air_quality_ = pd.concat([air_quality_pm25, air_quality_no2], keys=["PM25", "NO2"])
In [16]: air_quality_.head()
Out[16]:
date.utc location parameter value
PM25 0 2019-06-18 06:00:00+00:00 BETR801 pm25 18.0
1 2019-06-17 08:00:00+00:00 BETR801 pm25 6.5
2 2019-06-17 07:00:00+00:00 BETR801 pm25 18.5
3 2019-06-17 06:00:00+00:00 BETR801 pm25 16.0
4 2019-06-17 05:00:00+00:00 BETR801 pm25 7.5
注意
在这些教程中尚未提到同时存在多个行/列索引。分层索引或MultiIndex是一个用于分析更高维数据的高级且强大的 pandas 功能。
多重索引超出了本 pandas 入门范围。暂时记住函数reset_index
可以用于将索引的任何级别转换为列,例如air_quality.reset_index(level=0)
到用户指南
随意深入探讨高级索引用户指南部分中的多重索引世界。
到用户指南
在对象连接部分提供了有关表连接(行和列连接)的更多选项以及如何使用concat
定义在其他轴上的索引逻辑(并集或交集)。
使用共同标识符连接表
-
将由站点元数据表提供的站点坐标添加到测量表中的相应行。
警告
空气质量测量站坐标存储在数据文件
air_quality_stations.csv
中,使用py-openaq包下载。In [17]: stations_coord = pd.read_csv("data/air_quality_stations.csv") In [18]: stations_coord.head() Out[18]: location coordinates.latitude coordinates.longitude 0 BELAL01 51.23619 4.38522 1 BELHB23 51.17030 4.34100 2 BELLD01 51.10998 5.00486 3 BELLD02 51.12038 5.02155 4 BELR833 51.32766 4.36226
注意
此示例中使用的站点(FR04014、BETR801 和 London Westminster)只是元数据表中列出的三个条目。我们只想将这三个站点的坐标添加到测量表中,每个站点对应
air_quality
表的相应行。In [19]: air_quality.head() Out[19]: date.utc location parameter value 2067 2019-05-07 01:00:00+00:00 London Westminster no2 23.0 1003 2019-05-07 01:00:00+00:00 FR04014 no2 25.0 100 2019-05-07 01:00:00+00:00 BETR801 pm25 12.5 1098 2019-05-07 01:00:00+00:00 BETR801 no2 50.5 1109 2019-05-07 01:00:00+00:00 London Westminster pm25 8.0
In [20]: air_quality = pd.merge(air_quality, stations_coord, how="left", on="location") In [21]: air_quality.head() Out[21]: date.utc ... coordinates.longitude 0 2019-05-07 01:00:00+00:00 ... -0.13193 1 2019-05-07 01:00:00+00:00 ... 2.39390 2 2019-05-07 01:00:00+00:00 ... 2.39390 3 2019-05-07 01:00:00+00:00 ... 4.43182 4 2019-05-07 01:00:00+00:00 ... 4.43182 [5 rows x 6 columns]
使用
merge()
函数,对于air_quality
表中的每一行,从air_quality_stations_coord
表中添加相应的坐标。这两个表都有一个共同的location
列,用作组合信息的键。通过选择left
连接,最终表中只包含air_quality
(左)表中可用的位置,即 FR04014、BETR801 和 London Westminster。merge
函数支持类似数据库风格操作的多个连接选项。 -
将参数元数据表提供的参数完整描述和名称添加到测量表中。
警告
空气质量参数元数据存储在数据文件
air_quality_parameters.csv
中,使用py-openaq包下载。In [22]: air_quality_parameters = pd.read_csv("data/air_quality_parameters.csv") In [23]: air_quality_parameters.head() Out[23]: id description name 0 bc Black Carbon BC 1 co Carbon Monoxide CO 2 no2 Nitrogen Dioxide NO2 3 o3 Ozone O3 4 pm10 Particulate matter less than 10 micrometers in... PM10
In [24]: air_quality = pd.merge(air_quality, air_quality_parameters, ....: how='left', left_on='parameter', right_on='id') ....: In [25]: air_quality.head() Out[25]: date.utc ... name 0 2019-05-07 01:00:00+00:00 ... NO2 1 2019-05-07 01:00:00+00:00 ... NO2 2 2019-05-07 01:00:00+00:00 ... NO2 3 2019-05-07 01:00:00+00:00 ... PM2.5 4 2019-05-07 01:00:00+00:00 ... NO2 [5 rows x 9 columns]
与前面的示例相比,没有共同的列名。但是,在
air_quality
表中的parameter
列和air_quality_parameters_name
中的id
列都以共同格式提供了测量变量。这里使用left_on
和right_on
参数(而不仅仅是on
)来建立两个表之间的链接。
用户指南
pandas 还支持内部、外部和右连接。有关表的连接/合并的更多信息,请参阅用户指南中关于数据库风格表合并的部分。或者查看与 SQL 的比较页面。
记住
-
可以使用
concat
函数沿着列或行将多个表连接起来。 -
对于类似数据库的表合并/连接,请使用
merge
函数。
用户指南
查看用户指南,了解各种合并数据表的方法的详细描述。
连接对象
-
我想将(NO_2)和(PM_{25})的测量值,两个结构相似的表,合并到一个表中。
In [8]: air_quality = pd.concat([air_quality_pm25, air_quality_no2], axis=0) In [9]: air_quality.head() Out[9]: date.utc location parameter value 0 2019-06-18 06:00:00+00:00 BETR801 pm25 18.0 1 2019-06-17 08:00:00+00:00 BETR801 pm25 6.5 2 2019-06-17 07:00:00+00:00 BETR801 pm25 18.5 3 2019-06-17 06:00:00+00:00 BETR801 pm25 16.0 4 2019-06-17 05:00:00+00:00 BETR801 pm25 7.5
concat()
函数执行多个表沿一个轴(行或列)的连接操作。
默认情况下,沿轴 0 进行连接,因此生成的表将合并输入表的行。让我们检查原始表和连接表的形状以验证操作:
In [10]: print('Shape of the ``air_quality_pm25`` table: ', air_quality_pm25.shape)
Shape of the ``air_quality_pm25`` table: (1110, 4)
In [11]: print('Shape of the ``air_quality_no2`` table: ', air_quality_no2.shape)
Shape of the ``air_quality_no2`` table: (2068, 4)
In [12]: print('Shape of the resulting ``air_quality`` table: ', air_quality.shape)
Shape of the resulting ``air_quality`` table: (3178, 4)
因此,结果表有 3178 = 1110 + 2068 行。
注意
axis参数将返回一些可以沿着轴应用的 pandas 方法。DataFrame
有两个对应的轴:第一个沿着行垂直向下运行(轴 0),第二个沿着列水平运行(轴 1)。大多数操作(如连接或汇总统计)默认是沿着行(轴 0)进行的,但也可以沿着列进行。
根据日期时间信息对表进行排序也说明了两个表的组合,其中parameter
列定义了表的来源(air_quality_no2
表中的no2
或air_quality_pm25
表中的pm25
):
In [13]: air_quality = air_quality.sort_values("date.utc")
In [14]: air_quality.head()
Out[14]:
date.utc location parameter value
2067 2019-05-07 01:00:00+00:00 London Westminster no2 23.0
1003 2019-05-07 01:00:00+00:00 FR04014 no2 25.0
100 2019-05-07 01:00:00+00:00 BETR801 pm25 12.5
1098 2019-05-07 01:00:00+00:00 BETR801 no2 50.5
1109 2019-05-07 01:00:00+00:00 London Westminster pm25 8.0
在这个特定示例中,数据提供的parameter
列确保可以识别原始表中的每个表。这并非总是如此。concat
函数提供了一个方便的解决方案,使用keys
参数添加一个额外的(分层)行索引。例如:
In [15]: air_quality_ = pd.concat([air_quality_pm25, air_quality_no2], keys=["PM25", "NO2"])
In [16]: air_quality_.head()
Out[16]:
date.utc location parameter value
PM25 0 2019-06-18 06:00:00+00:00 BETR801 pm25 18.0
1 2019-06-17 08:00:00+00:00 BETR801 pm25 6.5
2 2019-06-17 07:00:00+00:00 BETR801 pm25 18.5
3 2019-06-17 06:00:00+00:00 BETR801 pm25 16.0
4 2019-06-17 05:00:00+00:00 BETR801 pm25 7.5
注意
在这些教程中没有提到同时存在多个行/列索引。层次化索引或MultiIndex是用于分析高维数据的高级且强大的 pandas 功能。
多重索引超出了本 pandas 介绍的范围。暂时记住函数reset_index
可用于将索引的任何级别转换为列,例如air_quality.reset_index(level=0)
用户指南
随时深入研究用户指南中关于高级索引的多重索引世界。
用户指南
提供了有关表连接的更多选项(按行和列)以及如何使用concat
来定义索引在其他轴上的逻辑(并集或交集)的信息,请参阅对象连接部分。
使用共同标识符连接表
-
将由站点元数据表提供的站点坐标添加到测量表中的相应行中。
警告
空气质量测量站点坐标存储在数据文件
air_quality_stations.csv
中,使用py-openaq包下载。In [17]: stations_coord = pd.read_csv("data/air_quality_stations.csv") In [18]: stations_coord.head() Out[18]: location coordinates.latitude coordinates.longitude 0 BELAL01 51.23619 4.38522 1 BELHB23 51.17030 4.34100 2 BELLD01 51.10998 5.00486 3 BELLD02 51.12038 5.02155 4 BELR833 51.32766 4.36226
注意
此示例中使用的站点(FR04014、BETR801 和 London Westminster)只是元数据表中列出的三个条目。我们只想将这三个站点的坐标添加到测量表中,每个站点对应
air_quality
表的相应行。In [19]: air_quality.head() Out[19]: date.utc location parameter value 2067 2019-05-07 01:00:00+00:00 London Westminster no2 23.0 1003 2019-05-07 01:00:00+00:00 FR04014 no2 25.0 100 2019-05-07 01:00:00+00:00 BETR801 pm25 12.5 1098 2019-05-07 01:00:00+00:00 BETR801 no2 50.5 1109 2019-05-07 01:00:00+00:00 London Westminster pm25 8.0
In [20]: air_quality = pd.merge(air_quality, stations_coord, how="left", on="location") In [21]: air_quality.head() Out[21]: date.utc ... coordinates.longitude 0 2019-05-07 01:00:00+00:00 ... -0.13193 1 2019-05-07 01:00:00+00:00 ... 2.39390 2 2019-05-07 01:00:00+00:00 ... 2.39390 3 2019-05-07 01:00:00+00:00 ... 4.43182 4 2019-05-07 01:00:00+00:00 ... 4.43182 [5 rows x 6 columns]
使用
merge()
函数,对于air_quality
表中的每一行,从air_quality_stations_coord
表中添加相应的坐标。这两个表格都有一个名为location
的列,用作合并信息的关键。通过选择left
连接,只有在air_quality
(左)表中可用的位置,即 FR04014、BETR801 和 London Westminster,最终出现在结果表中。merge
函数支持类似数据库操作的多个连接选项。 -
将参数元数据表提供的参数完整描述和名称添加到测量表中。
警告
空气质量参数元数据存储在数据文件
air_quality_parameters.csv
中,使用py-openaq包下载。In [22]: air_quality_parameters = pd.read_csv("data/air_quality_parameters.csv") In [23]: air_quality_parameters.head() Out[23]: id description name 0 bc Black Carbon BC 1 co Carbon Monoxide CO 2 no2 Nitrogen Dioxide NO2 3 o3 Ozone O3 4 pm10 Particulate matter less than 10 micrometers in... PM10
In [24]: air_quality = pd.merge(air_quality, air_quality_parameters, ....: how='left', left_on='parameter', right_on='id') ....: In [25]: air_quality.head() Out[25]: date.utc ... name 0 2019-05-07 01:00:00+00:00 ... NO2 1 2019-05-07 01:00:00+00:00 ... NO2 2 2019-05-07 01:00:00+00:00 ... NO2 3 2019-05-07 01:00:00+00:00 ... PM2.5 4 2019-05-07 01:00:00+00:00 ... NO2 [5 rows x 9 columns]
与前面的示例相比,这里没有共同的列名。然而,在
air_quality
表中的parameter
列和air_quality_parameters_name
中的id
列都以共同的格式提供了测量变量。这里使用left_on
和right_on
参数(而不仅仅是on
)来建立两个表格之间的链接。
至用户指南
pandas 还支持内部、外部和右连接。有关表格连接/合并的更多信息,请参阅用户指南中关于数据库风格表格合并的部分。或查看与 SQL 的比较页面。
记住
-
可以使用
concat
函数在列方向和行方向上连接多个表格。 -
对于类似数据库的表格合并/连接,请使用
merge
函数。
至用户指南
请参阅用户指南,了解各种数据表合并设施的详细描述。
如何轻松处理时间序列数据
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/09_timeseries.html
使用 pandas 日期时间属性
-
我想将列
datetime
中的日期作为日期对象而不是纯文本来处理In [7]: air_quality["datetime"] = pd.to_datetime(air_quality["datetime"]) In [8]: air_quality["datetime"] Out[8]: 0 2019-06-21 00:00:00+00:00 1 2019-06-20 23:00:00+00:00 2 2019-06-20 22:00:00+00:00 3 2019-06-20 21:00:00+00:00 4 2019-06-20 20:00:00+00:00 ... 2063 2019-05-07 06:00:00+00:00 2064 2019-05-07 04:00:00+00:00 2065 2019-05-07 03:00:00+00:00 2066 2019-05-07 02:00:00+00:00 2067 2019-05-07 01:00:00+00:00 Name: datetime, Length: 2068, dtype: datetime64[ns, UTC]
最初,
datetime
中的值是字符字符串,不提供任何日期时间操作(例如提取年份、星期几等)。通过应用to_datetime
函数,pandas 解释这些字符串并将其转换为日期时间(即datetime64[ns, UTC]
)对象。在 pandas 中,我们将这些日期时间对象称为类似于标准库中的datetime.datetime
的pandas.Timestamp
。
注意
由于许多数据集中的一列包含日期时间信息,pandas 输入函数如pandas.read_csv()
和pandas.read_json()
在读取数据时可以使用parse_dates
参数和要读取为 Timestamp 的列的列表进行日期转换:
pd.read_csv("../data/air_quality_no2_long.csv", parse_dates=["datetime"])
这些pandas.Timestamp
对象有什么用?让我们通过一些示例案例来说明其附加值。
我们正在处理的时间序列数据集的开始和结束日期是什么?
In [9]: air_quality["datetime"].min(), air_quality["datetime"].max()
Out[9]:
(Timestamp('2019-05-07 01:00:00+0000', tz='UTC'),
Timestamp('2019-06-21 00:00:00+0000', tz='UTC'))
使用pandas.Timestamp
处理日期时间使我们能够计算日期信息并使其可比较。因此,我们可以用这个来获取时间序列的长度:
In [10]: air_quality["datetime"].max() - air_quality["datetime"].min()
Out[10]: Timedelta('44 days 23:00:00')
结果是一个类似于标准 Python 库中的datetime.timedelta
的pandas.Timedelta
对象,定义了一个时间持续。
转到用户指南
pandas 支持的各种时间概念在用户指南的时间相关概念部分中有解释。
-
我想向
DataFrame
添加一个只包含测量月份的新列In [11]: air_quality["month"] = air_quality["datetime"].dt.month In [12]: air_quality.head() Out[12]: city country datetime ... value unit month 0 Paris FR 2019-06-21 00:00:00+00:00 ... 20.0 µg/m³ 6 1 Paris FR 2019-06-20 23:00:00+00:00 ... 21.8 µg/m³ 6 2 Paris FR 2019-06-20 22:00:00+00:00 ... 26.5 µg/m³ 6 3 Paris FR 2019-06-20 21:00:00+00:00 ... 24.9 µg/m³ 6 4 Paris FR 2019-06-20 20:00:00+00:00 ... 21.4 µg/m³ 6 [5 rows x 8 columns]
通过使用日期的
Timestamp
对象,pandas 提供了许多与时间相关的属性。例如month
,还有year
,quarter
���。所有这些属性都可以通过dt
访问器访问。
转到用户指南
现有日期属性的概述在时间和日期组件概述表中给出。关于dt
访问器返回类似日期时间的属性的更多细节在 dt 访问器的专用部分中有解释。
-
每天每个测量位置的平均(NO_2)浓度是多少?
In [13]: air_quality.groupby( ....: [air_quality["datetime"].dt.weekday, "location"])["value"].mean() ....: Out[13]: datetime location 0 BETR801 27.875000 FR04014 24.856250 London Westminster 23.969697 1 BETR801 22.214286 FR04014 30.999359 ... 5 FR04014 25.266154 London Westminster 24.977612 6 BETR801 21.896552 FR04014 23.274306 London Westminster 24.859155 Name: value, Length: 21, dtype: float64
还记得来自统计计算教程的
groupby
提供的分割-应用-合并模式吗?在这里,我们想要计算给定统计量(例如均值(NO_2))每个工作日和每个测量位置的数据。为了按工作日分组,我们使用 pandasTimestamp
的 datetime 属性weekday
(星期一=0,星期日=6),该属性也可以通过dt
访问器访问。可以对位置和工作日进行分组,以便在每个组合上分割均值的计算。危险
由于在这些示例中我们使用的是非常短的时间序列,因此分析结果并不代表长期结果!
-
绘制所有站点时间序列中一天内的典型(NO_2)模式。换句话说,每小时的平均值是多少?
In [14]: fig, axs = plt.subplots(figsize=(12, 4)) In [15]: air_quality.groupby(air_quality["datetime"].dt.hour)["value"].mean().plot( ....: kind='bar', rot=0, ax=axs ....: ) ....: Out[15]: <Axes: xlabel='datetime'> In [16]: plt.xlabel("Hour of the day"); # custom x label using Matplotlib In [17]: plt.ylabel("$NO_2 (µg/m³)$");
与前一个案例类似,我们想要计算给定统计量(例如均值(NO_2))每小时的数据,并且我们可以再次使用分割-应用-合并的方法。对于这种情况,我们使用 pandas
Timestamp
的 datetime 属性hour
,该属性也可以通过dt
访问器访问。
日期时间作为索引
在重塑教程中,介绍了pivot()
用于将数据表重塑,使每个测量位置成为单独的列:
In [18]: no_2 = air_quality.pivot(index="datetime", columns="location", values="value")
In [19]: no_2.head()
Out[19]:
location BETR801 FR04014 London Westminster
datetime
2019-05-07 01:00:00+00:00 50.5 25.0 23.0
2019-05-07 02:00:00+00:00 45.0 27.7 19.0
2019-05-07 03:00:00+00:00 NaN 50.4 19.0
2019-05-07 04:00:00+00:00 NaN 61.9 16.0
2019-05-07 05:00:00+00:00 NaN 72.4 NaN
注意
通过数据透视,日期时间信息成为表格的索引。通常,通过set_index
函数可以将列设置为索引。
使用日期时间索引(即DatetimeIndex
)提供了强大的功能。例如,我们不需要dt
访问器来获取时间序列属性,而是直接在索引上可用这些属性:
In [20]: no_2.index.year, no_2.index.weekday
Out[20]:
(Index([2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019,
...
2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019],
dtype='int32', name='datetime', length=1033),
Index([1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
...
3, 3, 3, 3, 3, 3, 3, 3, 3, 4],
dtype='int32', name='datetime', length=1033))
其他一些优点包括方便的时间段子集或图表上的调整时间刻度。让我们在我们的数据上应用这个。
-
创建一个图表,显示从 5 月 20 日到 5 月 21 日结束的不同站点的(NO_2)值
In [21]: no_2["2019-05-20":"2019-05-21"].plot();
通过提供一个解析为日期时间的字符串,可以在
DatetimeIndex
上选择特定的数据子集。
用户指南
有关DatetimeIndex
和使用字符串进行切片的更多信息,请参阅时间序列索引部分。
将时间序列重新采样为另一个频率
-
将当前每小时时间序列值聚合到每个站点的月最大值。
In [22]: monthly_max = no_2.resample("ME").max() In [23]: monthly_max Out[23]: location BETR801 FR04014 London Westminster datetime 2019-05-31 00:00:00+00:00 74.5 97.0 97.0 2019-06-30 00:00:00+00:00 52.5 84.7 52.0
在具有日期时间索引的时间序列数据上,一种非常强大的方法是能够将时间序列
重采样()
到另一个频率(例如,将每秒数据转换为每 5 分钟数据)。
resample()
方法类似于分组操作:
-
它提供基于时间的分组,通过使用定义目标频率的字符串(例如
M
、5H
,...) -
它需要聚合函数,如
mean
、max
等
到用户指南
有关用于定义时间序列频率的别名的概述可在偏移别名概述表中找到。
在定义时,时间序列的频率由freq
属性提供:
In [24]: monthly_max.index.freq
Out[24]: <MonthEnd>
-
绘制每个站点每日平均(NO_2)值的图表。
In [25]: no_2.resample("D").mean().plot(style="-o", figsize=(10, 5));
到用户指南
有关时间序列重采样
强大功能的更多细节,请参阅用户指南中关于重采样的部分。
记住
-
有效的日期字符串可以使用
to_datetime
函数或作为读取函数的一部分转换为日期时间对象。 -
pandas 中的日期时间对象支持计算、逻辑操作和使用
dt
访问器的便捷日期相关属性。 -
DatetimeIndex
包含这些与日期相关的属性,并支持便捷的切片。 -
重采样
是一种强大的方法,可以改变时间序列的频率。
到用户指南
有关时间序列的完整概述可在时间序列和日期功能页面上找到。
使用 pandas 日期时间属性
-
我想要将列
datetime
中的日期作为日期时间对象而不是纯文本进行处理In [7]: air_quality["datetime"] = pd.to_datetime(air_quality["datetime"]) In [8]: air_quality["datetime"] Out[8]: 0 2019-06-21 00:00:00+00:00 1 2019-06-20 23:00:00+00:00 2 2019-06-20 22:00:00+00:00 3 2019-06-20 21:00:00+00:00 4 2019-06-20 20:00:00+00:00 ... 2063 2019-05-07 06:00:00+00:00 2064 2019-05-07 04:00:00+00:00 2065 2019-05-07 03:00:00+00:00 2066 2019-05-07 02:00:00+00:00 2067 2019-05-07 01:00:00+00:00 Name: datetime, Length: 2068, dtype: datetime64[ns, UTC]
最初,
datetime
中的值是字符字符串,不提供任何日期时间操作(例如提取年份、星期几等)。通过应用to_datetime
函数,pandas 解释这些字符串并将其转换为日期时间(即datetime64[ns, UTC]
)对象。在 pandas 中,我们将这些日期时间对象称为类似于标准库中的datetime.datetime
的pandas.Timestamp
。
注意
由于许多数据集中的一列包含日期时间信息,因此 pandas 输入函数如pandas.read_csv()
和pandas.read_json()
在读取数据时可以使用parse_dates
参数进行日期转换,参数是要读取为时间戳的列的列表:
pd.read_csv("../data/air_quality_no2_long.csv", parse_dates=["datetime"])
这些pandas.Timestamp
对象有什么用?让我们通过一些示例案例来说明其附加值。
我们正在处理的时间序列数据集的开始和结束日期是什么?
In [9]: air_quality["datetime"].min(), air_quality["datetime"].max()
Out[9]:
(Timestamp('2019-05-07 01:00:00+0000', tz='UTC'),
Timestamp('2019-06-21 00:00:00+0000', tz='UTC'))
使用pandas.Timestamp
来处理日期时间使我们能够计算日期信息并使其可比较。因此,我们可以用它来获取时间序列的长度:
In [10]: air_quality["datetime"].max() - air_quality["datetime"].min()
Out[10]: Timedelta('44 days 23:00:00')
结果是一个pandas.Timedelta
对象,类似于标准 Python 库中的datetime.timedelta
,定义了时间持续。
用户指南
pandas 支持的各种时间概念在时间相关概念的用户指南部分有详细解释。
-
我想要向
DataFrame
添加一个只包含测量月份的新列In [11]: air_quality["month"] = air_quality["datetime"].dt.month In [12]: air_quality.head() Out[12]: city country datetime ... value unit month 0 Paris FR 2019-06-21 00:00:00+00:00 ... 20.0 µg/m³ 6 1 Paris FR 2019-06-20 23:00:00+00:00 ... 21.8 µg/m³ 6 2 Paris FR 2019-06-20 22:00:00+00:00 ... 26.5 µg/m³ 6 3 Paris FR 2019-06-20 21:00:00+00:00 ... 24.9 µg/m³ 6 4 Paris FR 2019-06-20 20:00:00+00:00 ... 21.4 µg/m³ 6 [5 rows x 8 columns]
通过使用
Timestamp
对象作为日期,pandas 提供了许多与时间相关的属性。例如month
,还有year
,quarter
等等。所有这些属性都可以通过dt
访问器访问。
用户指南
时间和日期组件概览表中提供了现有日期属性的概述。关于dt
访问器返回类似日期时间属性的更多细节在 dt 访问器的专门部分有解释。
-
每周每天每个测量位置的平均(NO_2)浓度是多少?
In [13]: air_quality.groupby( ....: [air_quality["datetime"].dt.weekday, "location"])["value"].mean() ....: Out[13]: datetime location 0 BETR801 27.875000 FR04014 24.856250 London Westminster 23.969697 1 BETR801 22.214286 FR04014 30.999359 ... 5 FR04014 25.266154 London Westminster 24.977612 6 BETR801 21.896552 FR04014 23.274306 London Westminster 24.859155 Name: value, Length: 21, dtype: float64
还记得
groupby
提供的分割-应用-合并模式吗?在统计计算教程中,我们想要计算每个工作日和每个测量位置的给定统计量(例如平均(NO_2))。为了按工作日分组,我们使用 pandasTimestamp
的日期时间属性weekday
(星期一=0,星期日=6),这也可以通过dt
访问器访问。可以对位置和工作日进行分组,以便在这些组合中分别计算平均值。危险
在这些示例中,我们处理的时间序列非常短,分析结果并不提供长期代表性的结果!
-
绘制我们所有站点时间序列中一天内典型的(NO_2)模式。换句话说,每个小时的平均值是多少?
In [14]: fig, axs = plt.subplots(figsize=(12, 4)) In [15]: air_quality.groupby(air_quality["datetime"].dt.hour)["value"].mean().plot( ....: kind='bar', rot=0, ax=axs ....: ) ....: Out[15]: <Axes: xlabel='datetime'> In [16]: plt.xlabel("Hour of the day"); # custom x label using Matplotlib In [17]: plt.ylabel("$NO_2 (µg/m³)$");
类似于前面的情况,我们想要计算每个小时的给定统计量(例如平均(NO_2)),我们可以再次使用分割-应用-合并方法。对于这种情况,我们使用 pandas
Timestamp
的日期时间属性hour
,这也可以通过dt
访问器访问。
日期时间作为索引
在重塑教程中,介绍了使用pivot()
来将数据表重塑,使每个测量位置成为单独的列:
In [18]: no_2 = air_quality.pivot(index="datetime", columns="location", values="value")
In [19]: no_2.head()
Out[19]:
location BETR801 FR04014 London Westminster
datetime
2019-05-07 01:00:00+00:00 50.5 25.0 23.0
2019-05-07 02:00:00+00:00 45.0 27.7 19.0
2019-05-07 03:00:00+00:00 NaN 50.4 19.0
2019-05-07 04:00:00+00:00 NaN 61.9 16.0
2019-05-07 05:00:00+00:00 NaN 72.4 NaN
注意
通过数据透视,日期时间信息成为表的索引。通常,通过set_index
函数可以将列设置为索引。
使用日期时间索引(即DatetimeIndex
)提供了强大的功���。例如,我们不需要dt
访问器来获取时间序列属性,而是直接在索引上可用这些属性:
In [20]: no_2.index.year, no_2.index.weekday
Out[20]:
(Index([2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019,
...
2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019],
dtype='int32', name='datetime', length=1033),
Index([1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
...
3, 3, 3, 3, 3, 3, 3, 3, 3, 4],
dtype='int32', name='datetime', length=1033))
其他一些优点是方便地对时间段进行子集划分或在图表上调整时间刻度。让我们在我们的数据上应用这个方法。
-
创建从 5 月 20 日到 5 月 21 日结束的不同站点(NO_2)值的图表。
In [21]: no_2["2019-05-20":"2019-05-21"].plot();
通过提供解析为日期时间的字符串,可以在
DatetimeIndex
上选择特定的数据子集。
到用户指南
更多关于DatetimeIndex
和使用字符串进行切片的信息,请参阅时间序列索引部分。
将时间序列重新采样到另一个频率
-
将当前每小时时间序列值聚合到各站点的每月最大值。
In [22]: monthly_max = no_2.resample("ME").max() In [23]: monthly_max Out[23]: location BETR801 FR04014 London Westminster datetime 2019-05-31 00:00:00+00:00 74.5 97.0 97.0 2019-06-30 00:00:00+00:00 52.5 84.7 52.0
在具有日期时间索引的时间序列数据上非常强大的方法是能够将时间序列
resample()
到另一个频率(例如,将每秒数据转换为每 5 分钟的数据)。
resample()
方法类似于分组操作:
-
它提供了基于时间的分组,通过使用定义目标频率的字符串(例如
M
、5H
等) -
它需要一个聚合函数,如
mean
、max
等。
到用户指南
在偏移别名概述表中提供了用于定义时间序列频率的别名的概述。
当定义时,时间序列的频率由freq
属性提供:
In [24]: monthly_max.index.freq
Out[24]: <MonthEnd>
-
绘制每个站点的每日平均(NO_2)值的图表。
In [25]: no_2.resample("D").mean().plot(style="-o", figsize=(10, 5));
到用户指南
更多关于时间序列重新采样
强大功能的详细信息,请参阅用户指南中的重新采样部分。
记住
-
有效的日期字符串可以使用
to_datetime
函数或作为读取函数的一部分转换为日期时间对象。 -
pandas 中的日期时间对象支持使用
dt
访问器进行计算、逻辑操作和方便的与日期相关的属性。 -
DatetimeIndex
包含这些与日期相关的属性,并支持方便的切片。 -
Resample
是改变时间序列频率的强大方法。
用户指南
有关时间序列的完整概述可在时间序列和日期功能页面上找到。
如何操作文本数据
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/10_text_data.html
-
将所有名称字符改为小写。
In [4]: titanic["Name"].str.lower() Out[4]: 0 braund, mr. owen harris 1 cumings, mrs. john bradley (florence briggs th... 2 heikkinen, miss. laina 3 futrelle, mrs. jacques heath (lily may peel) 4 allen, mr. william henry ... 886 montvila, rev. juozas 887 graham, miss. margaret edith 888 johnston, miss. catherine helen "carrie" 889 behr, mr. karl howell 890 dooley, mr. patrick Name: Name, Length: 891, dtype: object
要使
Name
列中的每个字符串都变为小写,选择Name
列(参见数据选择教程),添加str
访问器并应用lower
方法。因此,每个字符串都被逐个转换。
与时间序列教程中具有dt
访问器的日期时间对象类似,在使用str
访问器时可以使用许多专门的字符串方法。这些方法通常与单个元素的内置字符串方法具有匹配的名称,但是在每个值的列上逐个应用(记得逐元素计算吗?)。
-
创建一个新列
Surname
,其中包含乘客的姓氏,通过提取逗号前的部分。In [5]: titanic["Name"].str.split(",") Out[5]: 0 [Braund, Mr. Owen Harris] 1 [Cumings, Mrs. John Bradley (Florence Briggs ... 2 [Heikkinen, Miss. Laina] 3 [Futrelle, Mrs. Jacques Heath (Lily May Peel)] 4 [Allen, Mr. William Henry] ... 886 [Montvila, Rev. Juozas] 887 [Graham, Miss. Margaret Edith] 888 [Johnston, Miss. Catherine Helen "Carrie"] 889 [Behr, Mr. Karl Howell] 890 [Dooley, Mr. Patrick] Name: Name, Length: 891, dtype: object
使用
Series.str.split()
方法,每个值都返回一个包含 2 个元素的列表。第一个元素是逗号前的部分,第二个元素是逗号后的部分。In [6]: titanic["Surname"] = titanic["Name"].str.split(",").str.get(0) In [7]: titanic["Surname"] Out[7]: 0 Braund 1 Cumings 2 Heikkinen 3 Futrelle 4 Allen ... 886 Montvila 887 Graham 888 Johnston 889 Behr 890 Dooley Name: Surname, Length: 891, dtype: object
由于我们只对代表姓氏的第一部分感兴趣(元素 0),我们可以再次使用
str
访问器,并应用Series.str.get()
来提取相关部分。事实上,这些字符串函数可以连接起来组合多个函数!
到用户指南
有关提取字符串部分的更多信息,请参阅用户指南中关于拆分和替换字符串的部分。
-
提取关于泰坦尼克号上女伯爵的乘客数据。
In [8]: titanic["Name"].str.contains("Countess") Out[8]: 0 False 1 False 2 False 3 False 4 False ... 886 False 887 False 888 False 889 False 890 False Name: Name, Length: 891, dtype: bool
In [9]: titanic[titanic["Name"].str.contains("Countess")] Out[9]: PassengerId Survived Pclass ... Cabin Embarked Surname 759 760 1 1 ... B77 S Rothes [1 rows x 13 columns]
(对她的故事感兴趣吗?请参阅 维基百科!)
字符串方法
Series.str.contains()
检查列Name
中的每个值是否包含单词Countess
,并对每个值返回True
(Countess
是名称的一部分)或False
(Countess
不是名称的一部分)。此输出可用于使用在数据子集教程中介绍的条件(布尔)索引来对数据进行子选择。由于泰坦尼克号上只有一位女伯爵,我们得到一行作为结果。
注意
字符串的更强大的提取操作是支持的,因为Series.str.contains()
和 Series.str.extract()
方法接受正则表达式,但不在本教程的范围内。
到用户指南
更多有关提取字符串部分的信息,请参阅用户指南中有关字符串匹配和提取的部分。
-
泰坦尼克号的乘客中,哪位乘客的名字最长?
In [10]: titanic["Name"].str.len() Out[10]: 0 23 1 51 2 22 3 44 4 24 .. 886 21 887 28 888 40 889 21 890 19 Name: Name, Length: 891, dtype: int64
要获得最长的名称,我们首先必须获取
Name
列中每个名称的长度。通过使用 pandas 字符串方法,对每个名称单独应用Series.str.len()
函数(逐元素)。In [11]: titanic["Name"].str.len().idxmax() Out[11]: 307
接下来,我们需要获取对应位置,最好是表格中名字长度最大的索引标签。
idxmax()
方法正是这样做的。它不是字符串方法,适用于整数,因此不使用str
。In [12]: titanic.loc[titanic["Name"].str.len().idxmax(), "Name"] Out[12]: 'Penasco y Castellana, Mrs. Victor de Satode (Maria Josefa Perez de Soto y Vallejo)'
基于行的索引名称(
307
)和列的名称(Name
),我们可以使用loc
运算符进行选择,该运算符在子集切片教程中介绍过。 -
在“性别”列中,将“male”的值替换为“M”,将“female”的值替换为“F”。
In [13]: titanic["Sex_short"] = titanic["Sex"].replace({"male": "M", "female": "F"}) In [14]: titanic["Sex_short"] Out[14]: 0 M 1 F 2 F 3 F 4 M .. 886 M 887 F 888 F 889 M 890 M Name: Sex_short, Length: 891, dtype: object
而
replace()
不是一个字符串方法,它提供了一种方便的方式来使用映射或词汇表来转换某些值。它需要一个dictionary
来定义映射{from : to}
。
警告
还有一个可用的replace()
方法,可以替换特定的字符集。但是,当有多个值的映射时,这将变得:
titanic["Sex_short"] = titanic["Sex"].str.replace("female", "F")
titanic["Sex_short"] = titanic["Sex_short"].str.replace("male", "M")
这将变得繁琐,并且很容易出错。想想(或者试试)如果这两个语句以相反的顺序应用会发生什么…
记住
-
可以使用
str
访问器使用字符串方法。 -
字符串方法是逐元素进行的,可以用于条件索引。
-
replace
方法是根据给定字典转换值的便捷方法。
到用户指南
用户指南页面提供了处理文本数据的全面概述。
与其他工具的比较
原文:
pandas.pydata.org/docs/getting_started/comparison/index.html
-
与 R / R 库的比较
-
快速参考
-
基本 R
-
plyr
-
reshape / reshape2
-
-
与 SQL 的比较
-
复制 vs. 原地操作
-
选择
-
WHERE
-
GROUP BY
-
连接
-
UNION
-
限制
-
pandas 对一些 SQL 分析和聚合函数的等效操作
-
更新
-
删除
-
-
与电子表格的比较
-
数据结构
-
数据输入/输出
-
数据操作
-
字符串处理
-
合并
-
其他考虑因素
-
-
与 SAS 的比较
-
数据结构
-
数据输入/输出
-
数据操作
-
字符串处理
-
合并
-
缺失数据
-
GroupBy
-
其他考虑因素
-
-
与 Stata 的比较
-
数据结构
-
数据输入/输出
-
数据操作
-
字符串处理
-
合并
-
缺失数据
-
GroupBy
-
其他考虑因素
-
与 R/R 库的比较
译文:
pandas.pydata.org/docs/getting_started/comparison/comparison_with_r.html
由于 pandas 旨在提供许多人们使用R的数据操作和分析功能,因此本页面旨在更详细地查看R 语言及其许多第三方库与 pandas 的关系。在与 R 和 CRAN 库的比较中,我们关心以下几点:
-
功能性/灵活性:每个工具可以/不可以做什么
-
性能:操作有多快。最好提供硬性数据/基准
-
易用性:一个工具更容易/更难使用(您可能需要通过并排代码比较来判断)
本页面还提供了一个为这些 R 包的用户提供一点翻译指南的页面。
快速参考
我们将从一个快速参考指南开始,将一些常见的 R 操作(使用dplyr)与 pandas 的等效操作进行配对。
查询、过滤、抽样
R | pandas |
---|---|
dim(df) |
df.shape |
head(df) |
df.head() |
slice(df, 1:10) |
df.iloc[:9] |
filter(df, col1 == 1, col2 == 1) |
df.query('col1 == 1 & col2 == 1') |
df[df$col1 == 1 & df$col2 == 1,] |
df[(df.col1 == 1) & (df.col2 == 1)] |
select(df, col1, col2) |
df[['col1', 'col2']] |
select(df, col1:col3) |
df.loc[:, 'col1':'col3'] |
select(df, -(col1:col3)) |
df.drop(cols_to_drop, axis=1) 但请参见[1] |
distinct(select(df, col1)) |
df[['col1']].drop_duplicates() |
distinct(select(df, col1, col2)) |
df[['col1', 'col2']].drop_duplicates() |
sample_n(df, 10) |
df.sample(n=10) |
sample_frac(df, 0.01) |
df.sample(frac=0.01) |
排序
R | pandas |
---|---|
arrange(df, col1, col2) |
df.sort_values(['col1', 'col2']) |
arrange(df, desc(col1)) |
df.sort_values('col1', ascending=False) |
转换
R | pandas |
---|---|
select(df, col_one = col1) |
df.rename(columns={'col1': 'col_one'})['col_one'] |
rename(df, col_one = col1) |
df.rename(columns={'col1': 'col_one'}) |
mutate(df, c=a-b) |
df.assign(c=df['a']-df['b']) |
分组和汇总
R | pandas |
---|---|
summary(df) |
df.describe() |
gdf <- group_by(df, col1) |
gdf = df.groupby('col1') |
summarise(gdf, avg=mean(col1, na.rm=TRUE)) |
df.groupby('col1').agg({'col1': 'mean'}) |
summarise(gdf, total=sum(col1)) |
df.groupby('col1').sum() |
基础 R
使用 R 的c
进行切片
R 使得通过名称轻松访问 data.frame
列成为可能
df <- data.frame(a=rnorm(5), b=rnorm(5), c=rnorm(5), d=rnorm(5), e=rnorm(5))
df[, c("a", "c", "e")]
或按整数位置
df <- data.frame(matrix(rnorm(1000), ncol=100))
df[, c(1:10, 25:30, 40, 50:100)]
在 pandas 中按名称选择多列很简单
In [1]: df = pd.DataFrame(np.random.randn(10, 3), columns=list("abc"))
In [2]: df[["a", "c"]]
Out[2]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
In [3]: df.loc[:, ["a", "c"]]
Out[3]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
通过整数位置选择多个不连续列可以通过iloc
索引器属性和numpy.r_
的组合实现。
In [4]: named = list("abcdefg")
In [5]: n = 30
In [6]: columns = named + np.arange(len(named), n).tolist()
In [7]: df = pd.DataFrame(np.random.randn(n, n), columns=columns)
In [8]: df.iloc[:, np.r_[:10, 24:30]]
Out[8]:
a b c ... 27 28 29
0 -1.344312 0.844885 1.075770 ... 0.813850 0.132003 -0.827317
1 -0.076467 -1.187678 1.130127 ... 0.149748 -0.732339 0.687738
2 0.176444 0.403310 -0.154951 ... -0.493662 0.600178 0.274230
3 0.132885 -0.023688 2.410179 ... 0.109121 1.126203 -0.977349
4 1.474071 -0.064034 -1.282782 ... -0.858447 0.306996 -0.028665
.. ... ... ... ... ... ... ...
25 1.492125 -0.068190 0.681456 ... 0.428572 0.880609 0.487645
26 0.725238 0.624607 -0.141185 ... 1.008500 1.424017 0.717110
27 1.262419 1.950057 0.301038 ... 1.007824 2.826008 1.458383
28 -1.585746 -0.899734 0.921494 ... 0.577223 -1.088417 0.326687
29 -0.986248 0.169729 -1.158091 ... -2.013086 -1.602549 0.333109
[30 rows x 16 columns]
aggregate
在 R 中,您可能希望将数据拆分为子集并为每个子集计算平均值。使用名为df
的数据框,并将其拆分为by1
和by2
组:
df <- data.frame(
v1 = c(1,3,5,7,8,3,5,NA,4,5,7,9),
v2 = c(11,33,55,77,88,33,55,NA,44,55,77,99),
by1 = c("red", "blue", 1, 2, NA, "big", 1, 2, "red", 1, NA, 12),
by2 = c("wet", "dry", 99, 95, NA, "damp", 95, 99, "red", 99, NA, NA))
aggregate(x=df[, c("v1", "v2")], by=list(mydf2$by1, mydf2$by2), FUN = mean)
groupby()
方法类似于基本的 R aggregate
函数。
In [9]: df = pd.DataFrame(
...: {
...: "v1": [1, 3, 5, 7, 8, 3, 5, np.nan, 4, 5, 7, 9],
...: "v2": [11, 33, 55, 77, 88, 33, 55, np.nan, 44, 55, 77, 99],
...: "by1": ["red", "blue", 1, 2, np.nan, "big", 1, 2, "red", 1, np.nan, 12],
...: "by2": [
...: "wet",
...: "dry",
...: 99,
...: 95,
...: np.nan,
...: "damp",
...: 95,
...: 99,
...: "red",
...: 99,
...: np.nan,
...: np.nan,
...: ],
...: }
...: )
...:
In [10]: g = df.groupby(["by1", "by2"])
In [11]: g[["v1", "v2"]].mean()
Out[11]:
v1 v2
by1 by2
1 95 5.0 55.0
99 5.0 55.0
2 95 7.0 77.0
99 NaN NaN
big damp 3.0 33.0
blue dry 3.0 33.0
red red 4.0 44.0
wet 1.0 11.0
有关更多详细信息和示例,请参阅分组文档。
match
/ %in%
在 R 中选择数据的常见方法是使用%in%
,该运算符使用函数match
定义。运算符%in%
用于返回指示是否存在匹配项的逻辑向量:
s <- 0:4
s %in% c(2,4)
isin()
方法类似于 R 的%in%
运算符:
In [12]: s = pd.Series(np.arange(5), dtype=np.float32)
In [13]: s.isin([2, 4])
Out[13]:
0 False
1 False
2 True
3 False
4 True
dtype: bool
match
函数返回其第一个参数在第二个参数中匹配位置的向量:
s <- 0:4
match(s, c(2,4))
有关更多详细信息和示例,请参阅重塑文档。
tapply
tapply
类似于aggregate
,但数据可以是不规则的数组,因为子类大小可能不规则。使用名为baseball
的数据框,并根据数组team
检索信息:
baseball <-
data.frame(team = gl(5, 5,
labels = paste("Team", LETTERS[1:5])),
player = sample(letters, 25),
batting.average = runif(25, .200, .400))
tapply(baseball$batting.average, baseball.example$team,
max)
在 pandas 中,我们可以使用pivot_table()
方法来处理这个问题:
In [14]: import random
In [15]: import string
In [16]: baseball = pd.DataFrame(
....: {
....: "team": ["team %d" % (x + 1) for x in range(5)] * 5,
....: "player": random.sample(list(string.ascii_lowercase), 25),
....: "batting avg": np.random.uniform(0.200, 0.400, 25),
....: }
....: )
....:
In [17]: baseball.pivot_table(values="batting avg", columns="team", aggfunc="max")
Out[17]:
team team 1 team 2 team 3 team 4 team 5
batting avg 0.352134 0.295327 0.397191 0.394457 0.396194
有关更多详细信息和示例,请参阅重塑文档。
subset
query()
方法类似于基本的 R subset
函数。在 R 中,您可能希望获取data.frame
的行,其中一列的值小于另一列的值:
df <- data.frame(a=rnorm(10), b=rnorm(10))
subset(df, a <= b)
df[df$a <= df$b,] # note the comma
在 pandas 中,有几种方法可以执行子集。您可以使用query()
或将表达式传递为索引/切片,以及标准布尔索引:
In [18]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [19]: df.query("a <= b")
Out[19]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [20]: df[df["a"] <= df["b"]]
Out[20]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [21]: df.loc[df["a"] <= df["b"]]
Out[21]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
有关更多详细信息和示例,请参阅查询文档。
with
在 R 中使用名为df
的数据框,其中包含a
和b
列的表达式将使用with
进行评估:
df <- data.frame(a=rnorm(10), b=rnorm(10))
with(df, a + b)
df$a + df$b # same as the previous expression
在 pandas 中,使用eval()
方法的等效表达式将是:
In [22]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [23]: df.eval("a + b")
Out[23]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
In [24]: df["a"] + df["b"] # same as the previous expression
Out[24]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
在某些情况下,eval()
比纯 Python 中的评估要快得多。更多详细信息和示例请参见 eval 文档。
plyr
plyr
是一个用于数据分析的 R 库,围绕着 R 中的三种数据结构 a
(数组)、l
(列表)和 d
(数据框)展开。下表显示了这些数据结构在 Python 中的映射方式。
R | Python |
---|---|
数组 | 列表 |
列表 | 字典或对象列表 |
data.frame | 数据框 |
ddply
在 R 中使用名为 df
的 data.frame 来按 month
汇总 x
的表达式:
require(plyr)
df <- data.frame(
x = runif(120, 1, 168),
y = runif(120, 7, 334),
z = runif(120, 1.7, 20.7),
month = rep(c(5,6,7,8),30),
week = sample(1:4, 120, TRUE)
)
ddply(df, .(month, week), summarize,
mean = round(mean(x), 2),
sd = round(sd(x), 2))
在 pandas 中,等效的表达式,使用 groupby()
方法,将是:
In [25]: df = pd.DataFrame(
....: {
....: "x": np.random.uniform(1.0, 168.0, 120),
....: "y": np.random.uniform(7.0, 334.0, 120),
....: "z": np.random.uniform(1.7, 20.7, 120),
....: "month": [5, 6, 7, 8] * 30,
....: "week": np.random.randint(1, 4, 120),
....: }
....: )
....:
In [26]: grouped = df.groupby(["month", "week"])
In [27]: grouped["x"].agg(["mean", "std"])
Out[27]:
mean std
month week
5 1 63.653367 40.601965
2 78.126605 53.342400
3 92.091886 57.630110
6 1 81.747070 54.339218
2 70.971205 54.687287
3 100.968344 54.010081
7 1 61.576332 38.844274
2 61.733510 48.209013
3 71.688795 37.595638
8 1 62.741922 34.618153
2 91.774627 49.790202
3 73.936856 60.773900
更多详细信息和示例请参见 分组文档。
reshape / reshape2
meltarray
在 R 中使用名为 a
的 3 维数组来将其融合成一个 data.frame 的表达式:
a <- array(c(1:23, NA), c(2,3,4))
data.frame(melt(a))
在 Python 中,由于 a
是一个列表,你可以简单地使用列表推导式。
In [28]: a = np.array(list(range(1, 24)) + [np.NAN]).reshape(2, 3, 4)
In [29]: pd.DataFrame([tuple(list(x) + [val]) for x, val in np.ndenumerate(a)])
Out[29]:
0 1 2 3
0 0 0 0 1.0
1 0 0 1 2.0
2 0 0 2 3.0
3 0 0 3 4.0
4 0 1 0 5.0
.. .. .. .. ...
19 1 1 3 20.0
20 1 2 0 21.0
21 1 2 1 22.0
22 1 2 2 23.0
23 1 2 3 NaN
[24 rows x 4 columns]
meltlist
在 R 中使用名为 a
的列表来将其融合成一个 data.frame 的表达式:
a <- as.list(c(1:4, NA))
data.frame(melt(a))
在 Python 中,这个列表将是一个元组的列表,因此 DataFrame()
方法将其转换为所需的数据框。
In [30]: a = list(enumerate(list(range(1, 5)) + [np.NAN]))
In [31]: pd.DataFrame(a)
Out[31]:
0 1
0 0 1.0
1 1 2.0
2 2 3.0
3 3 4.0
4 4 NaN
更多详细信息和示例请参见 数据结构入门文档。
meltdf
在 R 中使用名为 cheese
的 data.frame 来重新塑造数据框的表达式:
cheese <- data.frame(
first = c('John', 'Mary'),
last = c('Doe', 'Bo'),
height = c(5.5, 6.0),
weight = c(130, 150)
)
melt(cheese, id=c("first", "last"))
在 Python 中,melt()
方法是 R 中的等效方法:
In [32]: cheese = pd.DataFrame(
....: {
....: "first": ["John", "Mary"],
....: "last": ["Doe", "Bo"],
....: "height": [5.5, 6.0],
....: "weight": [130, 150],
....: }
....: )
....:
In [33]: pd.melt(cheese, id_vars=["first", "last"])
Out[33]:
first last variable value
0 John Doe height 5.5
1 Mary Bo height 6.0
2 John Doe weight 130.0
3 Mary Bo weight 150.0
In [34]: cheese.set_index(["first", "last"]).stack(future_stack=True) # alternative way
Out[34]:
first last
John Doe height 5.5
weight 130.0
Mary Bo height 6.0
weight 150.0
dtype: float64
更多详细信息和示例请参见 重塑文档。
cast
在 R 中,acast
是使用名为 df
的 data.frame 来转换为更高维数组的表达式:
df <- data.frame(
x = runif(12, 1, 168),
y = runif(12, 7, 334),
z = runif(12, 1.7, 20.7),
month = rep(c(5,6,7),4),
week = rep(c(1,2), 6)
)
mdf <- melt(df, id=c("month", "week"))
acast(mdf, week ~ month ~ variable, mean)
在 Python 中,最好的方法是利用 pivot_table()
:
In [35]: df = pd.DataFrame(
....: {
....: "x": np.random.uniform(1.0, 168.0, 12),
....: "y": np.random.uniform(7.0, 334.0, 12),
....: "z": np.random.uniform(1.7, 20.7, 12),
....: "month": [5, 6, 7] * 4,
....: "week": [1, 2] * 6,
....: }
....: )
....:
In [36]: mdf = pd.melt(df, id_vars=["month", "week"])
In [37]: pd.pivot_table(
....: mdf,
....: values="value",
....: index=["variable", "week"],
....: columns=["month"],
....: aggfunc="mean",
....: )
....:
Out[37]:
month 5 6 7
variable week
x 1 93.888747 98.762034 55.219673
2 94.391427 38.112932 83.942781
y 1 94.306912 279.454811 227.840449
2 87.392662 193.028166 173.899260
z 1 11.016009 10.079307 16.170549
2 8.476111 17.638509 19.003494
类似于在 R 中使用名为 df
的 data.frame 来基于 Animal
和 FeedType
聚合信息的 dcast
:
df <- data.frame(
Animal = c('Animal1', 'Animal2', 'Animal3', 'Animal2', 'Animal1',
'Animal2', 'Animal3'),
FeedType = c('A', 'B', 'A', 'A', 'B', 'B', 'A'),
Amount = c(10, 7, 4, 2, 5, 6, 2)
)
dcast(df, Animal ~ FeedType, sum, fill=NaN)
# Alternative method using base R
with(df, tapply(Amount, list(Animal, FeedType), sum))
Python 可以通过两种不同的方式来处理这个问题。首先,类似于上面使用 pivot_table()
:
In [38]: df = pd.DataFrame(
....: {
....: "Animal": [
....: "Animal1",
....: "Animal2",
....: "Animal3",
....: "Animal2",
....: "Animal1",
....: "Animal2",
....: "Animal3",
....: ],
....: "FeedType": ["A", "B", "A", "A", "B", "B", "A"],
....: "Amount": [10, 7, 4, 2, 5, 6, 2],
....: }
....: )
....:
In [39]: df.pivot_table(values="Amount", index="Animal", columns="FeedType", aggfunc="sum")
Out[39]:
FeedType A B
Animal
Animal1 10.0 5.0
Animal2 2.0 13.0
Animal3 6.0 NaN
第二种方法是使用 groupby()
方法:
In [40]: df.groupby(["Animal", "FeedType"])["Amount"].sum()
Out[40]:
Animal FeedType
Animal1 A 10
B 5
Animal2 A 2
B 13
Animal3 A 6
Name: Amount, dtype: int64
更多详细信息和示例请参见 重塑文档 或 分组文档。
factor
pandas 有一种用于分类数据的数据类型。
cut(c(1,2,3,4,5,6), 3)
factor(c(1,2,3,2,2,3))
在 pandas 中可以用 pd.cut
和 astype("category")
实现:
In [41]: pd.cut(pd.Series([1, 2, 3, 4, 5, 6]), 3)
Out[41]:
0 (0.995, 2.667]
1 (0.995, 2.667]
2 (2.667, 4.333]
3 (2.667, 4.333]
4 (4.333, 6.0]
5 (4.333, 6.0]
dtype: category
Categories (3, interval[float64, right]): [(0.995, 2.667] < (2.667, 4.333] < (4.333, 6.0]]
In [42]: pd.Series([1, 2, 3, 2, 2, 3]).astype("category")
Out[42]:
0 1
1 2
2 3
3 2
4 2
5 3
dtype: category
Categories (3, int64): [1, 2, 3]
更多详情和示例请参阅 分类简介 和 API 文档。还有关于 与 R 的因子的区别 的文档。
快速参考
我们将从一个快速参考指南开始,将一些常见的 R 操作(使用 dplyr)与 pandas 的等价操作进行对比。
查询、过滤、抽样
R | pandas |
---|---|
dim(df) |
df.shape |
head(df) |
df.head() |
slice(df, 1:10) |
df.iloc[:9] |
filter(df, col1 == 1, col2 == 1) |
df.query('col1 == 1 & col2 == 1') |
df[df$col1 == 1 & df$col2 == 1,] |
df[(df.col1 == 1) & (df.col2 == 1)] |
select(df, col1, col2) |
df[['col1', 'col2']] |
select(df, col1:col3) |
df.loc[:, 'col1':'col3'] |
select(df, -(col1:col3)) |
df.drop(cols_to_drop, axis=1) 但见 [1] |
distinct(select(df, col1)) |
df[['col1']].drop_duplicates() |
distinct(select(df, col1, col2)) |
df[['col1', 'col2']].drop_duplicates() |
sample_n(df, 10) |
df.sample(n=10) |
sample_frac(df, 0.01) |
df.sample(frac=0.01) |
排序
R | pandas |
---|---|
arrange(df, col1, col2) |
df.sort_values(['col1', 'col2']) |
arrange(df, desc(col1)) |
df.sort_values('col1', ascending=False) |
转换
R | pandas |
---|---|
select(df, col_one = col1) |
df.rename(columns={'col1': 'col_one'})['col_one'] |
rename(df, col_one = col1) |
df.rename(columns={'col1': 'col_one'}) |
mutate(df, c=a-b) |
df.assign(c=df['a']-df['b']) |
分组和汇总
R | pandas |
---|---|
summary(df) |
df.describe() |
gdf <- group_by(df, col1) |
gdf = df.groupby('col1') |
summarise(gdf, avg=mean(col1, na.rm=TRUE)) |
df.groupby('col1').agg({'col1': 'mean'}) |
summarise(gdf, total=sum(col1)) |
df.groupby('col1').sum() |
查询、过滤、抽样
R | pandas |
---|---|
dim(df) |
df.shape |
head(df) |
df.head() |
slice(df, 1:10) |
df.iloc[:9] |
filter(df, col1 == 1, col2 == 1) |
df.query('col1 == 1 & col2 == 1') |
df[df$col1 == 1 & df$col2 == 1,] |
df[(df.col1 == 1) & (df.col2 == 1)] |
select(df, col1, col2) |
df[['col1', 'col2']] |
select(df, col1:col3) |
df.loc[:, 'col1':'col3'] |
select(df, -(col1:col3)) |
df.drop(cols_to_drop, axis=1) 但见 [1] |
distinct(select(df, col1)) |
df[['col1']].drop_duplicates() |
distinct(select(df, col1, col2)) |
df[['col1', 'col2']].drop_duplicates() |
sample_n(df, 10) |
df.sample(n=10) |
sample_frac(df, 0.01) |
df.sample(frac=0.01) |
排序
R | pandas |
---|---|
arrange(df, col1, col2) |
df.sort_values(['col1', 'col2']) |
arrange(df, desc(col1)) |
df.sort_values('col1', ascending=False) |
转换
R | pandas |
---|---|
select(df, col_one = col1) |
df.rename(columns={'col1': 'col_one'})['col_one'] |
rename(df, col_one = col1) |
df.rename(columns={'col1': 'col_one'}) |
mutate(df, c=a-b) |
df.assign(c=df['a']-df['b']) |
分组和汇总
R | pandas |
---|---|
summary(df) |
df.describe() |
gdf <- group_by(df, col1) |
gdf = df.groupby('col1') |
summarise(gdf, avg=mean(col1, na.rm=TRUE)) |
df.groupby('col1').agg({'col1': 'mean'}) |
summarise(gdf, total=sum(col1)) |
df.groupby('col1').sum() |
基本 R
使用 R 的 c
进行切片
R 使得通过名称轻松访问 data.frame
列
df <- data.frame(a=rnorm(5), b=rnorm(5), c=rnorm(5), d=rnorm(5), e=rnorm(5))
df[, c("a", "c", "e")]
或通过整数位置
df <- data.frame(matrix(rnorm(1000), ncol=100))
df[, c(1:10, 25:30, 40, 50:100)]
在 pandas 中通过名称选择多列很简单
In [1]: df = pd.DataFrame(np.random.randn(10, 3), columns=list("abc"))
In [2]: df[["a", "c"]]
Out[2]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
In [3]: df.loc[:, ["a", "c"]]
Out[3]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
通过整数位置选择多个不连续的列可以通过 iloc
索引器属性和 numpy.r_
的组合实现。
In [4]: named = list("abcdefg")
In [5]: n = 30
In [6]: columns = named + np.arange(len(named), n).tolist()
In [7]: df = pd.DataFrame(np.random.randn(n, n), columns=columns)
In [8]: df.iloc[:, np.r_[:10, 24:30]]
Out[8]:
a b c ... 27 28 29
0 -1.344312 0.844885 1.075770 ... 0.813850 0.132003 -0.827317
1 -0.076467 -1.187678 1.130127 ... 0.149748 -0.732339 0.687738
2 0.176444 0.403310 -0.154951 ... -0.493662 0.600178 0.274230
3 0.132885 -0.023688 2.410179 ... 0.109121 1.126203 -0.977349
4 1.474071 -0.064034 -1.282782 ... -0.858447 0.306996 -0.028665
.. ... ... ... ... ... ... ...
25 1.492125 -0.068190 0.681456 ... 0.428572 0.880609 0.487645
26 0.725238 0.624607 -0.141185 ... 1.008500 1.424017 0.717110
27 1.262419 1.950057 0.301038 ... 1.007824 2.826008 1.458383
28 -1.585746 -0.899734 0.921494 ... 0.577223 -1.088417 0.326687
29 -0.986248 0.169729 -1.158091 ... -2.013086 -1.602549 0.333109
[30 rows x 16 columns]
aggregate
在 R 中,您可能希望将数据拆分为子集,并为每个子集计算平均值。使用名为 df
的数据框,并将其拆分为 by1
和 by2
组:
df <- data.frame(
v1 = c(1,3,5,7,8,3,5,NA,4,5,7,9),
v2 = c(11,33,55,77,88,33,55,NA,44,55,77,99),
by1 = c("red", "blue", 1, 2, NA, "big", 1, 2, "red", 1, NA, 12),
by2 = c("wet", "dry", 99, 95, NA, "damp", 95, 99, "red", 99, NA, NA))
aggregate(x=df[, c("v1", "v2")], by=list(mydf2$by1, mydf2$by2), FUN = mean)
groupby()
方法类似于基本的 R aggregate
函数。
In [9]: df = pd.DataFrame(
...: {
...: "v1": [1, 3, 5, 7, 8, 3, 5, np.nan, 4, 5, 7, 9],
...: "v2": [11, 33, 55, 77, 88, 33, 55, np.nan, 44, 55, 77, 99],
...: "by1": ["red", "blue", 1, 2, np.nan, "big", 1, 2, "red", 1, np.nan, 12],
...: "by2": [
...: "wet",
...: "dry",
...: 99,
...: 95,
...: np.nan,
...: "damp",
...: 95,
...: 99,
...: "red",
...: 99,
...: np.nan,
...: np.nan,
...: ],
...: }
...: )
...:
In [10]: g = df.groupby(["by1", "by2"])
In [11]: g[["v1", "v2"]].mean()
Out[11]:
v1 v2
by1 by2
1 95 5.0 55.0
99 5.0 55.0
2 95 7.0 77.0
99 NaN NaN
big damp 3.0 33.0
blue dry 3.0 33.0
red red 4.0 44.0
wet 1.0 11.0
有关更多详细信息和示例,请参阅分组文档。
match
/ %in%
用 %in%
在 R 中选择数据的常见方法是使用 match
函数定义的。操作符 %in%
用于返回一个逻辑向量,指示是否有匹配项:
s <- 0:4
s %in% c(2,4)
isin()
方法类似于 R 的 %in%
操作符:
In [12]: s = pd.Series(np.arange(5), dtype=np.float32)
In [13]: s.isin([2, 4])
Out[13]:
0 False
1 False
2 True
3 False
4 True
dtype: bool
match
函数返回其第一个参数在第二个参数中的匹配位置的向量:
s <- 0:4
match(s, c(2,4))
有关更多详细信息和示例,请参阅重塑文档。
tapply
tapply
类似于 aggregate
,但数据可以是不规则的,因为子类大小可能不规则。使用名为 baseball
的数据框,并根据数组 team
检索信息:
baseball <-
data.frame(team = gl(5, 5,
labels = paste("Team", LETTERS[1:5])),
player = sample(letters, 25),
batting.average = runif(25, .200, .400))
tapply(baseball$batting.average, baseball.example$team,
max)
在 pandas 中,我们可以使用 pivot_table()
方法来处理这个问题:
In [14]: import random
In [15]: import string
In [16]: baseball = pd.DataFrame(
....: {
....: "team": ["team %d" % (x + 1) for x in range(5)] * 5,
....: "player": random.sample(list(string.ascii_lowercase), 25),
....: "batting avg": np.random.uniform(0.200, 0.400, 25),
....: }
....: )
....:
In [17]: baseball.pivot_table(values="batting avg", columns="team", aggfunc="max")
Out[17]:
team team 1 team 2 team 3 team 4 team 5
batting avg 0.352134 0.295327 0.397191 0.394457 0.396194
有关更多详细信息和示例,请参阅重塑文档。
subset
query()
方法类似于基本的 R subset
函数。在 R 中,您可能希望获取data.frame
的行,其中一列的值小于另一列的值:
df <- data.frame(a=rnorm(10), b=rnorm(10))
subset(df, a <= b)
df[df$a <= df$b,] # note the comma
在 pandas 中,有几种执行子集的方法。您可以使用query()
或将表达式传递为索引/切片,以及标准布尔索引:
In [18]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [19]: df.query("a <= b")
Out[19]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [20]: df[df["a"] <= df["b"]]
Out[20]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [21]: df.loc[df["a"] <= df["b"]]
Out[21]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
更多详细信息和示例请参见查询文档。
with
在 R 中使用名为df
的数据框(data.frame)和列a
和b
的表达式将使用with
进行评估,如下所示:
df <- data.frame(a=rnorm(10), b=rnorm(10))
with(df, a + b)
df$a + df$b # same as the previous expression
在 pandas 中,使用eval()
方法的等价表达式将是:
In [22]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [23]: df.eval("a + b")
Out[23]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
In [24]: df["a"] + df["b"] # same as the previous expression
Out[24]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
在某些情况下,eval()
比纯 Python 中的评估要快得多。更多详细信息和示例请参见评估文档。
使用 R 的c
进行切片
R 可以轻松通过名称访问data.frame
列
df <- data.frame(a=rnorm(5), b=rnorm(5), c=rnorm(5), d=rnorm(5), e=rnorm(5))
df[, c("a", "c", "e")]
或通过整数位置
df <- data.frame(matrix(rnorm(1000), ncol=100))
df[, c(1:10, 25:30, 40, 50:100)]
在 pandas 中按名称选择多个列非常简单
In [1]: df = pd.DataFrame(np.random.randn(10, 3), columns=list("abc"))
In [2]: df[["a", "c"]]
Out[2]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
In [3]: df.loc[:, ["a", "c"]]
Out[3]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
通过iloc
索引器属性和numpy.r_
的组合可以实现通过整数位置选择多个非连续列。
In [4]: named = list("abcdefg")
In [5]: n = 30
In [6]: columns = named + np.arange(len(named), n).tolist()
In [7]: df = pd.DataFrame(np.random.randn(n, n), columns=columns)
In [8]: df.iloc[:, np.r_[:10, 24:30]]
Out[8]:
a b c ... 27 28 29
0 -1.344312 0.844885 1.075770 ... 0.813850 0.132003 -0.827317
1 -0.076467 -1.187678 1.130127 ... 0.149748 -0.732339 0.687738
2 0.176444 0.403310 -0.154951 ... -0.493662 0.600178 0.274230
3 0.132885 -0.023688 2.410179 ... 0.109121 1.126203 -0.977349
4 1.474071 -0.064034 -1.282782 ... -0.858447 0.306996 -0.028665
.. ... ... ... ... ... ... ...
25 1.492125 -0.068190 0.681456 ... 0.428572 0.880609 0.487645
26 0.725238 0.624607 -0.141185 ... 1.008500 1.424017 0.717110
27 1.262419 1.950057 0.301038 ... 1.007824 2.826008 1.458383
28 -1.585746 -0.899734 0.921494 ... 0.577223 -1.088417 0.326687
29 -0.986248 0.169729 -1.158091 ... -2.013086 -1.602549 0.333109
[30 rows x 16 columns]
aggregate
在 R 中,您可能希望将数据拆分为子集并为每个子集计算平均值。使用名为df
的数据框,并将其拆分为组by1
和by2
:
df <- data.frame(
v1 = c(1,3,5,7,8,3,5,NA,4,5,7,9),
v2 = c(11,33,55,77,88,33,55,NA,44,55,77,99),
by1 = c("red", "blue", 1, 2, NA, "big", 1, 2, "red", 1, NA, 12),
by2 = c("wet", "dry", 99, 95, NA, "damp", 95, 99, "red", 99, NA, NA))
aggregate(x=df[, c("v1", "v2")], by=list(mydf2$by1, mydf2$by2), FUN = mean)
groupby()
方法类似于基本的 R aggregate
函数。
In [9]: df = pd.DataFrame(
...: {
...: "v1": [1, 3, 5, 7, 8, 3, 5, np.nan, 4, 5, 7, 9],
...: "v2": [11, 33, 55, 77, 88, 33, 55, np.nan, 44, 55, 77, 99],
...: "by1": ["red", "blue", 1, 2, np.nan, "big", 1, 2, "red", 1, np.nan, 12],
...: "by2": [
...: "wet",
...: "dry",
...: 99,
...: 95,
...: np.nan,
...: "damp",
...: 95,
...: 99,
...: "red",
...: 99,
...: np.nan,
...: np.nan,
...: ],
...: }
...: )
...:
In [10]: g = df.groupby(["by1", "by2"])
In [11]: g[["v1", "v2"]].mean()
Out[11]:
v1 v2
by1 by2
1 95 5.0 55.0
99 5.0 55.0
2 95 7.0 77.0
99 NaN NaN
big damp 3.0 33.0
blue dry 3.0 33.0
red red 4.0 44.0
wet 1.0 11.0
更多详细信息和示例请参见分组文档。
match
/ %in%
在 R 中选择数据的常见方式是使用%in%
,该运算符使用match
函数定义。运算符%in%
用于返回一个逻辑向量,指示是否存在匹配项:
s <- 0:4
s %in% c(2,4)
isin()
方法类似于 R 的%in%
运算符:
In [12]: s = pd.Series(np.arange(5), dtype=np.float32)
In [13]: s.isin([2, 4])
Out[13]:
0 False
1 False
2 True
3 False
4 True
dtype: bool
match
函数返回其第一个参数在第二个参数中匹配位置的向量:
s <- 0:4
match(s, c(2,4))
更多详细信息和示例请参见重塑文档。
tapply
tapply
类似于 aggregate
,但数据可以是不规则的数组,因为子类大小可能不规则。使用名为 baseball
的 data.frame,并根据数组 team
检索信息:
baseball <-
data.frame(team = gl(5, 5,
labels = paste("Team", LETTERS[1:5])),
player = sample(letters, 25),
batting.average = runif(25, .200, .400))
tapply(baseball$batting.average, baseball.example$team,
max)
在 pandas 中,我们可以使用pivot_table()
方法来处理这个问题:
In [14]: import random
In [15]: import string
In [16]: baseball = pd.DataFrame(
....: {
....: "team": ["team %d" % (x + 1) for x in range(5)] * 5,
....: "player": random.sample(list(string.ascii_lowercase), 25),
....: "batting avg": np.random.uniform(0.200, 0.400, 25),
....: }
....: )
....:
In [17]: baseball.pivot_table(values="batting avg", columns="team", aggfunc="max")
Out[17]:
team team 1 team 2 team 3 team 4 team 5
batting avg 0.352134 0.295327 0.397191 0.394457 0.396194
更多详细信息和示例请参见重塑文档。
subset
query()
方法类似于基本的 R subset
函数。在 R 中,您可能希望获取 data.frame
的行,其中一个列的值小于另一个列的值:
df <- data.frame(a=rnorm(10), b=rnorm(10))
subset(df, a <= b)
df[df$a <= df$b,] # note the comma
在 pandas 中,有几种方法可以执行子集。您可以使用query()
或将表达式传递为索引/切片,以及标准布尔索引:
In [18]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [19]: df.query("a <= b")
Out[19]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [20]: df[df["a"] <= df["b"]]
Out[20]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [21]: df.loc[df["a"] <= df["b"]]
Out[21]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
更多详细信息和示例请参见查询文档。
with
在 R 中使用名为 df
的 data.frame,具有列 a
和 b
,将使用 with
进行评估,如下所示:
df <- data.frame(a=rnorm(10), b=rnorm(10))
with(df, a + b)
df$a + df$b # same as the previous expression
在 pandas 中,等效的��达式,使用eval()
方法,将是:
In [22]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [23]: df.eval("a + b")
Out[23]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
In [24]: df["a"] + df["b"] # same as the previous expression
Out[24]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
在某些情况下,eval()
比纯 Python 中的评估要快得多。更多详细信息和示例请参见 eval 文档。
plyr
plyr
是用于数据分析的分割-应用-组合策略的 R 库。这些函数围绕 R 中的三种数据结构展开,a
代表 arrays
,l
代表 lists
,d
代表 data.frame
。下表显示了这些数据结构在 Python 中的映射方式。
R | Python |
---|---|
array | list |
lists | 字典或对象列表 |
data.frame | dataframe |
ddply
在 R 中使用名为 df
的 data.frame 表达式,您想要按 month
汇总 x
:
require(plyr)
df <- data.frame(
x = runif(120, 1, 168),
y = runif(120, 7, 334),
z = runif(120, 1.7, 20.7),
month = rep(c(5,6,7,8),30),
week = sample(1:4, 120, TRUE)
)
ddply(df, .(month, week), summarize,
mean = round(mean(x), 2),
sd = round(sd(x), 2))
在 pandas 中,等效的表达式,使用groupby()
方法,将是:
In [25]: df = pd.DataFrame(
....: {
....: "x": np.random.uniform(1.0, 168.0, 120),
....: "y": np.random.uniform(7.0, 334.0, 120),
....: "z": np.random.uniform(1.7, 20.7, 120),
....: "month": [5, 6, 7, 8] * 30,
....: "week": np.random.randint(1, 4, 120),
....: }
....: )
....:
In [26]: grouped = df.groupby(["month", "week"])
In [27]: grouped["x"].agg(["mean", "std"])
Out[27]:
mean std
month week
5 1 63.653367 40.601965
2 78.126605 53.342400
3 92.091886 57.630110
6 1 81.747070 54.339218
2 70.971205 54.687287
3 100.968344 54.010081
7 1 61.576332 38.844274
2 61.733510 48.209013
3 71.688795 37.595638
8 1 62.741922 34.618153
2 91.774627 49.790202
3 73.936856 60.773900
更多详细信息和示例请参见分组文档。
ddply
在 R 中使用名为 df
的 data.frame 表达式,您想要按 month
汇总 x
:
require(plyr)
df <- data.frame(
x = runif(120, 1, 168),
y = runif(120, 7, 334),
z = runif(120, 1.7, 20.7),
month = rep(c(5,6,7,8),30),
week = sample(1:4, 120, TRUE)
)
ddply(df, .(month, week), summarize,
mean = round(mean(x), 2),
sd = round(sd(x), 2))
在 pandas 中,等效的表达式,使用groupby()
方法,将是:
In [25]: df = pd.DataFrame(
....: {
....: "x": np.random.uniform(1.0, 168.0, 120),
....: "y": np.random.uniform(7.0, 334.0, 120),
....: "z": np.random.uniform(1.7, 20.7, 120),
....: "month": [5, 6, 7, 8] * 30,
....: "week": np.random.randint(1, 4, 120),
....: }
....: )
....:
In [26]: grouped = df.groupby(["month", "week"])
In [27]: grouped["x"].agg(["mean", "std"])
Out[27]:
mean std
month week
5 1 63.653367 40.601965
2 78.126605 53.342400
3 92.091886 57.630110
6 1 81.747070 54.339218
2 70.971205 54.687287
3 100.968344 54.010081
7 1 61.576332 38.844274
2 61.733510 48.209013
3 71.688795 37.595638
8 1 62.741922 34.618153
2 91.774627 49.790202
3 73.936856 60.773900
更多细节和示例请参见分组文档。
reshape / reshape2
meltarray
在 R 中使用名为a
的三维数组的表达式,你想要将其融化成数据框:
a <- array(c(1:23, NA), c(2,3,4))
data.frame(melt(a))
在 Python 中,由于a
是一个列表,你可以简单地使用列表推导式。
In [28]: a = np.array(list(range(1, 24)) + [np.NAN]).reshape(2, 3, 4)
In [29]: pd.DataFrame([tuple(list(x) + [val]) for x, val in np.ndenumerate(a)])
Out[29]:
0 1 2 3
0 0 0 0 1.0
1 0 0 1 2.0
2 0 0 2 3.0
3 0 0 3 4.0
4 0 1 0 5.0
.. .. .. .. ...
19 1 1 3 20.0
20 1 2 0 21.0
21 1 2 1 22.0
22 1 2 2 23.0
23 1 2 3 NaN
[24 rows x 4 columns]
meltlist
在 R 中使用名为a
的列表的表达式,你想要将其融化成数据框:
a <- as.list(c(1:4, NA))
data.frame(melt(a))
在 Python 中,这个列表将是一个元组的列表,所以DataFrame()
方法会将其转换为所需的数据框。
In [30]: a = list(enumerate(list(range(1, 5)) + [np.NAN]))
In [31]: pd.DataFrame(a)
Out[31]:
0 1
0 0 1.0
1 1 2.0
2 2 3.0
3 3 4.0
4 4 NaN
更多细节和示例请参见数据结构介绍文档。
meltdf
在 R 中使用名为cheese
的数据框的表达式,你想要重塑数据框:
cheese <- data.frame(
first = c('John', 'Mary'),
last = c('Doe', 'Bo'),
height = c(5.5, 6.0),
weight = c(130, 150)
)
melt(cheese, id=c("first", "last"))
在 Python 中,melt()
方法是 R 的等价物:
In [32]: cheese = pd.DataFrame(
....: {
....: "first": ["John", "Mary"],
....: "last": ["Doe", "Bo"],
....: "height": [5.5, 6.0],
....: "weight": [130, 150],
....: }
....: )
....:
In [33]: pd.melt(cheese, id_vars=["first", "last"])
Out[33]:
first last variable value
0 John Doe height 5.5
1 Mary Bo height 6.0
2 John Doe weight 130.0
3 Mary Bo weight 150.0
In [34]: cheese.set_index(["first", "last"]).stack(future_stack=True) # alternative way
Out[34]:
first last
John Doe height 5.5
weight 130.0
Mary Bo height 6.0
weight 150.0
dtype: float64
更多细节和示��请参见重塑文档。
转换
在 R 中,acast
是一个使用名为df
的数据框来转换为更高维数组的表达式:
df <- data.frame(
x = runif(12, 1, 168),
y = runif(12, 7, 334),
z = runif(12, 1.7, 20.7),
month = rep(c(5,6,7),4),
week = rep(c(1,2), 6)
)
mdf <- melt(df, id=c("month", "week"))
acast(mdf, week ~ month ~ variable, mean)
在 Python 中,最好的方法是利用pivot_table()
:
In [35]: df = pd.DataFrame(
....: {
....: "x": np.random.uniform(1.0, 168.0, 12),
....: "y": np.random.uniform(7.0, 334.0, 12),
....: "z": np.random.uniform(1.7, 20.7, 12),
....: "month": [5, 6, 7] * 4,
....: "week": [1, 2] * 6,
....: }
....: )
....:
In [36]: mdf = pd.melt(df, id_vars=["month", "week"])
In [37]: pd.pivot_table(
....: mdf,
....: values="value",
....: index=["variable", "week"],
....: columns=["month"],
....: aggfunc="mean",
....: )
....:
Out[37]:
month 5 6 7
variable week
x 1 93.888747 98.762034 55.219673
2 94.391427 38.112932 83.942781
y 1 94.306912 279.454811 227.840449
2 87.392662 193.028166 173.899260
z 1 11.016009 10.079307 16.170549
2 8.476111 17.638509 19.003494
类似于dcast
,它使用在 R 中名为df
的数据框来根据Animal
和FeedType
聚合信息的表达式:
df <- data.frame(
Animal = c('Animal1', 'Animal2', 'Animal3', 'Animal2', 'Animal1',
'Animal2', 'Animal3'),
FeedType = c('A', 'B', 'A', 'A', 'B', 'B', 'A'),
Amount = c(10, 7, 4, 2, 5, 6, 2)
)
dcast(df, Animal ~ FeedType, sum, fill=NaN)
# Alternative method using base R
with(df, tapply(Amount, list(Animal, FeedType), sum))
Python 可以用两种不同的方式来处理这个问题。首先,类似于上面使用pivot_table()
:
In [38]: df = pd.DataFrame(
....: {
....: "Animal": [
....: "Animal1",
....: "Animal2",
....: "Animal3",
....: "Animal2",
....: "Animal1",
....: "Animal2",
....: "Animal3",
....: ],
....: "FeedType": ["A", "B", "A", "A", "B", "B", "A"],
....: "Amount": [10, 7, 4, 2, 5, 6, 2],
....: }
....: )
....:
In [39]: df.pivot_table(values="Amount", index="Animal", columns="FeedType", aggfunc="sum")
Out[39]:
FeedType A B
Animal
Animal1 10.0 5.0
Animal2 2.0 13.0
Animal3 6.0 NaN
第二种方法是使用groupby()
方法:
In [40]: df.groupby(["Animal", "FeedType"])["Amount"].sum()
Out[40]:
Animal FeedType
Animal1 A 10
B 5
Animal2 A 2
B 13
Animal3 A 6
Name: Amount, dtype: int64
更多细节和示例请参见重塑文档或分组文档。
factor
pandas 有一个用于分类数据的数据类型。
cut(c(1,2,3,4,5,6), 3)
factor(c(1,2,3,2,2,3))
在 pandas 中,可以通过pd.cut
和astype("category")
来实现:
In [41]: pd.cut(pd.Series([1, 2, 3, 4, 5, 6]), 3)
Out[41]:
0 (0.995, 2.667]
1 (0.995, 2.667]
2 (2.667, 4.333]
3 (2.667, 4.333]
4 (4.333, 6.0]
5 (4.333, 6.0]
dtype: category
Categories (3, interval[float64, right]): [(0.995, 2.667] < (2.667, 4.333] < (4.333, 6.0]]
In [42]: pd.Series([1, 2, 3, 2, 2, 3]).astype("category")
Out[42]:
0 1
1 2
2 3
3 2
4 2
5 3
dtype: category
Categories (3, int64): [1, 2, 3]
更多细节和示例请参见分类介绍和 API 文档。还有关于 R 的因子的差异的文档。
meltarray
在 R 中使用名为a
的三维数组的表达式,你想要将其融化成数据框:
a <- array(c(1:23, NA), c(2,3,4))
data.frame(melt(a))
在 Python 中,由于a
是一个列表,你可以简单地使用列表推导式。
In [28]: a = np.array(list(range(1, 24)) + [np.NAN]).reshape(2, 3, 4)
In [29]: pd.DataFrame([tuple(list(x) + [val]) for x, val in np.ndenumerate(a)])
Out[29]:
0 1 2 3
0 0 0 0 1.0
1 0 0 1 2.0
2 0 0 2 3.0
3 0 0 3 4.0
4 0 1 0 5.0
.. .. .. .. ...
19 1 1 3 20.0
20 1 2 0 21.0
21 1 2 1 22.0
22 1 2 2 23.0
23 1 2 3 NaN
[24 rows x 4 columns]
meltlist
在 R 中使用名为a
的列表的表达式,你想要将其融化成数据框:
a <- as.list(c(1:4, NA))
data.frame(melt(a))
在 Python 中,这个列表将是一个元组的列表,所以DataFrame()
方法会将其转换为所需的数据框。
In [30]: a = list(enumerate(list(range(1, 5)) + [np.NAN]))
In [31]: pd.DataFrame(a)
Out[31]:
0 1
0 0 1.0
1 1 2.0
2 2 3.0
3 3 4.0
4 4 NaN
更多详细信息和示例请参见数据结构介绍文档。
meltdf
在 R 中使用名为cheese
的数据框进行数据重塑的表达式:
cheese <- data.frame(
first = c('John', 'Mary'),
last = c('Doe', 'Bo'),
height = c(5.5, 6.0),
weight = c(130, 150)
)
melt(cheese, id=c("first", "last"))
在 Python 中,melt()
方法相当于 R 中的:
In [32]: cheese = pd.DataFrame(
....: {
....: "first": ["John", "Mary"],
....: "last": ["Doe", "Bo"],
....: "height": [5.5, 6.0],
....: "weight": [130, 150],
....: }
....: )
....:
In [33]: pd.melt(cheese, id_vars=["first", "last"])
Out[33]:
first last variable value
0 John Doe height 5.5
1 Mary Bo height 6.0
2 John Doe weight 130.0
3 Mary Bo weight 150.0
In [34]: cheese.set_index(["first", "last"]).stack(future_stack=True) # alternative way
Out[34]:
first last
John Doe height 5.5
weight 130.0
Mary Bo height 6.0
weight 150.0
dtype: float64
更多详细信息和示例请参见重塑文档。
cast
在 R 中,acast
是使用名为df
的数据框进行高维数组转换的表达式:
df <- data.frame(
x = runif(12, 1, 168),
y = runif(12, 7, 334),
z = runif(12, 1.7, 20.7),
month = rep(c(5,6,7),4),
week = rep(c(1,2), 6)
)
mdf <- melt(df, id=c("month", "week"))
acast(mdf, week ~ month ~ variable, mean)
在 Python 中,最佳方式是利用pivot_table()
:
In [35]: df = pd.DataFrame(
....: {
....: "x": np.random.uniform(1.0, 168.0, 12),
....: "y": np.random.uniform(7.0, 334.0, 12),
....: "z": np.random.uniform(1.7, 20.7, 12),
....: "month": [5, 6, 7] * 4,
....: "week": [1, 2] * 6,
....: }
....: )
....:
In [36]: mdf = pd.melt(df, id_vars=["month", "week"])
In [37]: pd.pivot_table(
....: mdf,
....: values="value",
....: index=["variable", "week"],
....: columns=["month"],
....: aggfunc="mean",
....: )
....:
Out[37]:
month 5 6 7
variable week
x 1 93.888747 98.762034 55.219673
2 94.391427 38.112932 83.942781
y 1 94.306912 279.454811 227.840449
2 87.392662 193.028166 173.899260
z 1 11.016009 10.079307 16.170549
2 8.476111 17.638509 19.003494
类似于dcast
,它使用 R 中名为df
的数据框根据Animal
和FeedType
聚合信息:
df <- data.frame(
Animal = c('Animal1', 'Animal2', 'Animal3', 'Animal2', 'Animal1',
'Animal2', 'Animal3'),
FeedType = c('A', 'B', 'A', 'A', 'B', 'B', 'A'),
Amount = c(10, 7, 4, 2, 5, 6, 2)
)
dcast(df, Animal ~ FeedType, sum, fill=NaN)
# Alternative method using base R
with(df, tapply(Amount, list(Animal, FeedType), sum))
Python 可以通过两种不同的方式来实现。首先,类似于上面使用pivot_table()
:
In [38]: df = pd.DataFrame(
....: {
....: "Animal": [
....: "Animal1",
....: "Animal2",
....: "Animal3",
....: "Animal2",
....: "Animal1",
....: "Animal2",
....: "Animal3",
....: ],
....: "FeedType": ["A", "B", "A", "A", "B", "B", "A"],
....: "Amount": [10, 7, 4, 2, 5, 6, 2],
....: }
....: )
....:
In [39]: df.pivot_table(values="Amount", index="Animal", columns="FeedType", aggfunc="sum")
Out[39]:
FeedType A B
Animal
Animal1 10.0 5.0
Animal2 2.0 13.0
Animal3 6.0 NaN
第二种方法是使用groupby()
方法:
In [40]: df.groupby(["Animal", "FeedType"])["Amount"].sum()
Out[40]:
Animal FeedType
Animal1 A 10
B 5
Animal2 A 2
B 13
Animal3 A 6
Name: Amount, dtype: int64
更多详细信息和示例请参见重塑文档或分组文档。
factor
pandas 有一种用于分类数据的数据类型。
cut(c(1,2,3,4,5,6), 3)
factor(c(1,2,3,2,2,3))
在 pandas 中,可以通过pd.cut
和astype("category")
来实现:
In [41]: pd.cut(pd.Series([1, 2, 3, 4, 5, 6]), 3)
Out[41]:
0 (0.995, 2.667]
1 (0.995, 2.667]
2 (2.667, 4.333]
3 (2.667, 4.333]
4 (4.333, 6.0]
5 (4.333, 6.0]
dtype: category
Categories (3, interval[float64, right]): [(0.995, 2.667] < (2.667, 4.333] < (4.333, 6.0]]
In [42]: pd.Series([1, 2, 3, 2, 2, 3]).astype("category")
Out[42]:
0 1
1 2
2 3
3 2
4 2
5 3
dtype: category
Categories (3, int64): [1, 2, 3]
更多详细信息和示例请参见分类介绍和 API 文档。还有一份关于 R 中因子的差异的文档。