Pandas 是 Pythonopen in new window 的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。Pandas 的目标是成为 Python 数据分析实践与实战的必备高级工具,其长远目标是成为最强大、最灵活、可以支持任何语言的开源数据分析工具。经过多年不懈的努力,Pandas 离这个目标已经越来越近了。
Pandas 适用于处理以下类型的数据:
与 SQL 或 Excel 表类似的,含异构列的表格数据;
有序和无序(非固定频率)的时间序列数据;
带行列标签的矩阵数据,包括同构或异构型数据;
任意其它形式的观测、统计数据集, 数据转入 Pandas 数据结构时不必事先标记。
Pandas 的主要数据结构是 Seriesopen in new window(一维数据)与 DataFrameopen in new window(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。对于 R 用户,DataFrame 提供了比 R 语言 data.frame 更丰富的功能。Pandas 基于 NumPyopen in new window 开发,可以与其它第三方科学计算支持库完美集成。
Pandas 就像一把万能瑞士军刀,下面仅列出了它的部分优势 :
处理浮点与非浮点数据里的缺失数据,表示为 NaN
;
大小可变:插入或删除 DataFrame 等多维对象的列;
自动、显式数据对齐:显式地将对象与一组标签对齐,也可以忽略标签,在 Series、DataFrame 计算时自动与数据对齐;
强大、灵活的分组(group by)功能:拆分-应用-组合数据集,聚合、转换数据;
把 Python 和 NumPy 数据结构里不规则、不同索引的数据轻松地转换为 DataFrame 对象;
基于智能标签,对大型数据集进行切片、花式索引、子集分解等操作;
直观地合并(merge)、连接(join)数据集;
灵活地重塑(reshape)、透视(pivot)数据集;
轴支持结构化标签:一个刻度支持多个标签;
成熟的 IO 工具:读取文本文件(CSV 等支持分隔符的文件)、Excel 文件、数据库等来源的数据,利用超快的 HDF5 格式保存 / 加载数据;
时间序列:支持日期范围生成、频率转换、移动窗口统计、移动窗口线性回归、日期位移等时间序列功能。
这些功能主要是为了解决其它编程语言、科研环境的痛点。处理数据一般分为几个阶段:数据整理与清洗、数据分析与建模、数据可视化与制表,Pandas 是处理数据的理想工具。
其它说明:
Pandas 速度很快。Pandas 的很多底层算法都用 Cythonopen in new window 优化过。然而,为了保持通用性,必然要牺牲一些性能,如果专注某一功能,完全可以开发出比 Pandas 更快的专用工具。
Pandas 是 statsmodelsopen in new window 的依赖项,因此,Pandas 也是 Python 中统计计算生态系统的重要组成部分。
Pandas 已广泛应用于金融领域。
维数 | 名称 | 描述 |
---|---|---|
1 | Series | 带标签的一维同构数组 |
2 | DataFrame | 带标签的,大小可变的,二维异构表格 |
Pandas 数据结构就像是低维数据的容器。比如,DataFrame 是 Series 的容器,Series 则是标量的容器。使用这种方式,可以在容器中以字典的形式插入或删除对象。
此外,通用 API 函数的默认操作要顾及时间序列与截面数据集的方向。多维数组存储二维或三维数据时,编写函数要注意数据集的方向,这对用户来说是一种负担;如果不考虑 C 或 Fortran 中连续性对性能的影响,一般情况下,不同的轴在程序里其实没有什么区别。Pandas 里,轴的概念主要是为了给数据赋予更直观的语义,即用“更恰当”的方式表示数据集的方向。这样做可以让用户编写数据转换函数时,少费点脑子。
处理 DataFrame 等表格数据时,index(行)或 columns(列)比 axis 0 和 axis 1 更直观。用这种方式迭代 DataFrame 的列,代码更易读易懂:
- for col in df.columns:
- series = df[col]
- # do something with series
-
-
- import pandas as pd
- import random
- from faker import Faker
- from openpyxl import Workbook
-
- # 创建虚假数据生成器
- fake = Faker()
-
- # 创建一个数据帧,生成虚假数据
- n=1000
- data = {
- '姓名': [fake.name() for _ in range(n)],
- '电子邮件': [fake.email() for _ in range(n)],
- '电话号码': [fake.phone_number() for _ in range(n)],
- '地址': [fake.address() for _ in range(n)],
- '工资': [random.randint(1000,10000) for _ in range(n)]
- }
-
- df = pd.DataFrame(data)
-
- # 创建一个Excel工作簿并将数据写入工作表
- wb = Workbook()
- ws = wb.active
-
- # 将数据帧的列标题写入工作表的第一行
- for col, column_name in enumerate(df.columns, start=1):
- ws.cell(row=1, column=col, value=column_name)
-
- # 将数据写入工作表
- for row, record in enumerate(df.values, start=2):
- for col, value in enumerate(record, start=1):
- ws.cell(row=row, column=col, value=value)
-
- # 保存Excel文件
- wb.save('虚假数据.xlsx')
-
- df=pd.read_excel('虚假数据.xlsx')
- for col in df.columns:
- series = df[col]
- print(col,series)
-
- 姓名 0 Susan Ortiz
- 1 Bryan Patterson
- 2 Betty Stevens
- 3 Tina Mendez
- 4 Edward Miller
- ...
- 995 Maria Davis
- 996 Stephanie Underwood
- 997 Nicole Robinson
- 998 Mr. Charles Lawrence MD
- 999 Angela Johnson
- Name: 姓名, Length: 1000, dtype: object
- 电子邮件 0 jeffrey05@example.net
- 1 xdavidson@example.com
- 2 henrykey@example.net
- 3 gchaney@example.com
- 4 awatts@example.org
- ...
- 995 kheath@example.com
- 996 loriwilliams@example.org
- 997 wmann@example.com
- 998 margaretfriedman@example.org
- 999 hrivers@example.net
- Name: 电子邮件, Length: 1000, dtype: object
- 电话号码 0 (551)885-6301x47608
- 1 1430520935
- 2 001-117-798-3751x241
- 3 701.251.0146x3110
- 4 180-238-9727x8554
- ...
- 995 340-283-5841x845
- 996 (668)810-5237x874
- 997 (844)113-8337
- 998 001-563-272-0102x6982
- 999 914-902-3095x90088
- Name: 电话号码, Length: 1000, dtype: object
- 地址 0 9266 Abbott Burg Suite 758\nNorth Stephanie, I...
- 1 439 Gonzalez Turnpike\nWest Zoechester, PA 51406
- 2 56319 Matthew Estate Apt. 619\nNorth Michael, ...
- 3 4664 Dawson Burgs\nLongmouth, MH 51592
- 4 485 Rogers Prairie Suite 472\nPearsonmouth, MP...
- ...
- 995 78764 Jennifer Squares Suite 495\nAimeetown, V...
- 996 739 Donald Mill Apt. 480\nJenniferstad, CT 56683
- 997 540 Christine Shoals\nRichardsview, IA 65480
- 998 20154 Craig Path Suite 691\nPetersonland, SD 8...
- 999 0537 Rebecca Lock Apt. 835\nLindsayport, MA 44282
- Name: 地址, Length: 1000, dtype: object
- 工资 0 9183
- 1 3573
- 2 7649
- 3 3934
- 4 1371
- ...
- 995 3751
- 996 2966
- 997 7967
- 998 3144
- 999 4289
- Name: 工资, Length: 1000, dtype: int64
Pandas 所有数据结构的值都是可变的,但数据结构的大小并非都是可变的,比如,Series 的长度不可改变,但 DataFrame 里就可以插入列。
Pandas 里,绝大多数方法都不改变原始的输入数据,而是复制数据,生成新的对象。 一般来说,原始输入数据不变更稳妥。
本节是帮助 Pandas 新手快速上手的简介。烹饪指南里介绍了更多实用案例。
本节以下列方式导入 Pandas 与 NumPy:
In [1]: import numpy as np In [2]: import pandas as pd
详见数据结构简介文档。
用值列表生成 Seriesopen in new window 时,Pandas 默认自动生成整数索引:
-
- In [3]: s = pd.Series([1, 3, 5, np.nan, 6, 8])
-
- In [4]: s
- Out[4]:
- 0 1.0
- 1 3.0
- 2 5.0
- 3 NaN
- 4 6.0
- 5 8.0
- dtype: float64
- 用含日期时间索引与标签的 NumPy 数组生成 DataFrameopen in new window:
-
- dates = pd.date_range('20130101', periods=6)
- print(dates)
- df=pd.DataFrame(np.random.random((6,5)),index=dates,columns=list('ABCDE'))
- print(df)
-
- DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
- '2013-01-05', '2013-01-06'],
- dtype='datetime64[ns]', freq='D')
- A B C D E
- 2013-01-01 0.821722 0.838978 0.684531 0.867492 0.084755
- 2013-01-02 0.784795 0.971571 0.509171 0.046268 0.806170
- 2013-01-03 0.546673 0.073271 0.738921 0.297711 0.735907
- 2013-01-04 0.621592 0.403766 0.802696 0.109643 0.171212
- 2013-01-05 0.469991 0.893711 0.461032 0.326327 0.424273
- 2013-01-06 0.680158 0.605057 0.230274 0.458527 0.647544
-
- 用 Series 字典对象生成 DataFrame:
-
- In [9]: df2 = pd.DataFrame({'A': 1.,
- ...: 'B': pd.Timestamp('20130102'),
- ...: 'C': pd.Series(1, index=list(range(4)), dtype='float32'),
- ...: 'D': np.array([3] * 4, dtype='int32'),
- ...: 'E': pd.Categorical(["test", "train", "test", "train"]),
- ...: 'F': 'foo'})
- ...:
-
- In [10]: df2
- Out[10]:
- A B C D E F
- 0 1.0 2013-01-02 1.0 3 test foo
- 1 1.0 2013-01-02 1.0 3 train foo
- 2 1.0 2013-01-02 1.0 3 test foo
- 3 1.0 2013-01-02 1.0 3 train foo
- DataFrame 的列有不同数据类型open in new window。
-
- In [11]: df2.dtypes
- Out[11]:
- A float64
- B datetime64[ns]
- C float32
- D int32
- E category
- F object
- dtype: object
- IPython支持 tab 键自动补全列名与公共属性。下面是部分可自动补全的属性:
-
- In [12]: df2.
# noqa: E225, E999 - df2.A df2.bool
- df2.abs df2.boxplot
- df2.add df2.C
- df2.add_prefix df2.clip
- df2.add_suffix df2.clip_lower
- df2.align df2.clip_upper
- df2.all df2.columns
- df2.any df2.combine
- df2.append df2.combine_first
- df2.apply df2.compound
- df2.applymap df2.consolidate
-
df2.D
列 A、B、C、D 和 E 都可以自动补全;为简洁起见,此处只显示了部分属性。
下列代码说明如何查看 DataFrame 头部和尾部数据:
- In [13]: df.head()
- Out[13]:
- A B C D
- 2013-01-01 0.469112 -0.282863 -1.509059 -1.135632
- 2013-01-02 1.212112 -0.173215 0.119209 -1.044236
- 2013-01-03 -0.861849 -2.104569 -0.49492