- Python Pandas 教程
- Python Pandas - 首页
- Python Pandas - 简介
- Python Pandas - 环境设置
- Python Pandas - 基础知识
- Python Pandas - 数据结构介绍
- Python Pandas - 索引对象
- Python Pandas - Panel
- Python Pandas - 基本功能
- Python Pandas - 索引和数据选择
- Python Pandas - Series
- Python Pandas - Series
- Python Pandas - 切片 Series 对象
- Python Pandas - Series 对象的属性
- Python Pandas - Series 对象的算术运算
- Python Pandas - 将 Series 转换为其他对象
- Python Pandas - DataFrame
- Python Pandas - DataFrame
- Python Pandas - 访问 DataFrame
- Python Pandas - 切片 DataFrame 对象
- Python Pandas - 修改 DataFrame
- Python Pandas - 从 DataFrame 中删除行
- Python Pandas - DataFrame 的算术运算
- Python Pandas - I/O 工具
- Python Pandas - I/O 工具
- Python Pandas - 使用 CSV 格式
- Python Pandas - 读取和写入 JSON 文件
- Python Pandas - 从 Excel 文件读取数据
- Python Pandas - 将数据写入 Excel 文件
- Python Pandas - 使用 HTML 数据
- Python Pandas - 剪贴板
- Python Pandas - 使用 HDF5 格式
- Python Pandas - 与 SQL 的比较
- Python Pandas - 数据处理
- Python Pandas - 排序
- Python Pandas - 重新索引
- Python Pandas - 迭代
- Python Pandas - 级联
- Python Pandas - 统计函数
- Python Pandas - 描述性统计
- Python Pandas - 使用文本数据
- Python Pandas - 函数应用
- Python Pandas - 选项和自定义
- Python Pandas - 窗口函数
- Python Pandas - 聚合
- Python Pandas - 合并/连接
- Python Pandas - 多层索引
- Python Pandas - 多层索引的基础知识
- Python Pandas - 使用多层索引进行索引
- Python Pandas - 使用多层索引进行高级重新索引
- Python Pandas - 重命名多层索引标签
- Python Pandas - 对多层索引进行排序
- Python Pandas - 二元运算
- Python Pandas - 二元比较运算
- Python Pandas - 布尔索引
- Python Pandas - 布尔掩码
- Python Pandas - 数据重塑和透视
- Python Pandas - 透视表
- Python Pandas - 堆叠和取消堆叠
- Python Pandas - 熔化
- Python Pandas - 计算虚拟变量
- Python Pandas - 分类数据
- Python Pandas - 分类数据
- Python Pandas - 分类数据的排序和排序
- Python Pandas - 比较分类数据
- Python Pandas - 处理缺失数据
- Python Pandas - 缺失数据
- Python Pandas - 填充缺失数据
- Python Pandas - 缺失值的插值
- Python Pandas - 删除缺失数据
- Python Pandas - 使用缺失数据进行计算
- Python Pandas - 处理重复项
- Python Pandas - 重复数据
- Python Pandas - 计数和检索唯一元素
- Python Pandas - 重复标签
- Python Pandas - 分组和聚合
- Python Pandas - GroupBy
- Python Pandas - 时间序列数据
- Python Pandas - 日期功能
- Python Pandas - Timedelta
- Python Pandas - 稀疏数据结构
- Python Pandas - 稀疏数据
- Python Pandas - 可视化
- Python Pandas - 可视化
- Python Pandas - 附加概念
- Python Pandas - 警告和陷阱
- Python Pandas 有用资源
- Python Pandas 快速指南
- Python Pandas - 有用资源
- Python Pandas - 讨论
Python Pandas 快速指南
Python Pandas - 简介
Pandas 是一个开源的 Python 库,它使用强大的数据结构提供高性能的数据操作和分析工具。Pandas 的名称来源于面板数据——计量经济学中的多维数据。
2008 年,开发者 Wes McKinney 在需要一个高性能、灵活的工具来分析数据时开始开发 pandas。
在 Pandas 之前,Python 主要用于数据清洗和准备。它对数据分析的贡献非常小。Pandas解决了这个问题。使用 Pandas,我们可以完成数据处理和分析中的五个典型步骤,无论数据来源如何——加载、准备、操作、建模和分析。
Python 与 Pandas 广泛应用于包括金融、经济学、统计学、分析学等在内的学术和商业领域。
Pandas 的关键特性
- 快速高效的 DataFrame 对象,具有默认和自定义索引。
- 用于将数据从不同文件格式加载到内存中数据对象的工具。
- 数据对齐和缺失数据的集成处理。
- 数据集的重塑和透视。
- 基于标签的大型数据集的切片、索引和子集选择。
- 可以删除或插入数据结构中的列。
- 对数据进行分组以进行聚合和转换。
- 高性能的数据合并和连接。
- 时间序列功能。
Python Pandas - 环境设置
标准 Python 发行版不包含 Pandas 模块。一个轻量级的替代方案是使用流行的 Python 包安装程序 **pip** 安装 NumPy。
pip install pandas
如果您安装 Anaconda Python 包,Pandas 将默认安装如下:
Windows
**Anaconda** (来自 https://www.continuum.io) 是一个免费的 SciPy 栈 Python 发行版。它也适用于 Linux 和 Mac。
**Canopy** (https://www.enthought.com/products/canopy/) 提供免费和商业发行版,包含适用于 Windows、Linux 和 Mac 的完整 SciPy 栈。
**Python(x,y)** 是一个免费的 Python 发行版,包含 SciPy 栈和 Spyder IDE,适用于 Windows 操作系统。(可从 http://python-xy.github.io/ 下载)
Linux
各个 Linux 发行版的包管理器用于安装 SciPy 栈中的一个或多个包。
对于 Ubuntu 用户
sudo apt-get install python-numpy python-scipy python-matplotlibipythonipythonnotebook python-pandas python-sympy python-nose
对于 Fedora 用户
sudo yum install numpyscipy python-matplotlibipython python-pandas sympy python-nose atlas-devel
数据结构介绍
Pandas 处理以下三种数据结构:
- Series
- DataFrame
- Panel
这些数据结构构建在 Numpy 数组之上,这意味着它们速度很快。
维度和描述
理解这些数据结构的最佳方法是,更高维的数据结构是其低维数据结构的容器。例如,DataFrame 是 Series 的容器,Panel 是 DataFrame 的容器。
数据结构 | 维度 | 描述 |
---|---|---|
Series | 1 | 一维带标签的同质数组,大小不可变。 |
DataFrame | 2 | 一般的二维带标签的、大小可变的表格结构,可能包含异构类型的列。 |
Panel | 3 | 一般的三维带标签的、大小可变的数组。 |
构建和处理两个或多个维度的数组是一项繁琐的任务,用户需要在编写函数时考虑数据集的方向。但是使用 Pandas 数据结构,可以减少用户的脑力负担。
例如,对于表格数据 (DataFrame),从语义上讲,考虑 **索引**(行)和 **列** 比考虑轴 0 和轴 1更有帮助。
可变性
所有 Pandas 数据结构的值都是可变的(可以更改),除了 Series 之外,所有数据结构的大小都是可变的。Series 的大小是不可变的。
**注意** - DataFrame 广泛使用,并且是最重要的数据结构之一。Panel 的使用要少得多。
Series
Series 是一种一维类似数组的结构,包含同质数据。例如,以下 Series 是整数 10、23、56……的集合。
10 | 23 | 56 | 17 | 52 | 61 | 73 | 90 | 26 | 72 |
关键点
- 同质数据
- 大小不可变
- 数据值可变
DataFrame
DataFrame 是一个二维数组,包含异构数据。例如:
姓名 | 年龄 | 性别 | 评分 |
---|---|---|---|
Steve | 32 | 男 | 3.45 |
Lia | 28 | 女 | 4.6 |
Vin | 45 | 男 | 3.9 |
Katie | 38 | 女 | 2.78 |
该表显示了一个组织销售团队的数据及其整体绩效评分。数据以行和列表示。每一列代表一个属性,每一行代表一个人。
列的数据类型
四列的数据类型如下:
列 | 类型 |
---|---|
姓名 | 字符串 |
年龄 | 整数 |
性别 | 字符串 |
评分 | 浮点数 |
关键点
- 异构数据
- 大小可变
- 数据可变
Panel
Panel 是一种三维数据结构,包含异构数据。很难用图形表示来表示 Panel。但是,Panel 可以被说明为 DataFrame 的容器。
关键点
- 异构数据
- 大小可变
- 数据可变
Python Pandas - Series
Series 是一种一维带标签的数组,能够保存任何类型的数据(整数、字符串、浮点数、Python 对象等)。轴标签统称为索引。
pandas.Series
可以使用以下构造函数创建 pandas Series:
pandas.Series( data, index, dtype, copy)
构造函数的参数如下:
序号 | 参数和描述 |
---|---|
1 |
data data 可以采用各种形式,例如 ndarray、列表、常量 |
2 |
index 索引值必须唯一且可哈希,与 data 长度相同。如果没有传递索引,则默认为 **np.arange(n)**。 |
3 |
dtype dtype 用于数据类型。如果为 None,则将推断数据类型 |
4 |
copy 复制数据。默认为 False |
可以使用各种输入创建 Series,例如:
- 数组
- 字典
- 标量值或常量
创建空 Series
可以创建的基本 Series 是空 Series。
示例
#import the pandas library and aliasing as pd import pandas as pd s = pd.Series() print s
其 **输出** 如下:
Series([], dtype: float64)
从 ndarray 创建 Series
如果 data 是一个 ndarray,则传递的 index 必须具有相同的长度。如果没有传递 index,则默认情况下 index 将为 **range(n)**,其中 **n** 是数组长度,即 [0,1,2,3…. **range(len(array))-1]。**
示例 1
#import the pandas library and aliasing as pd import pandas as pd import numpy as np data = np.array(['a','b','c','d']) s = pd.Series(data) print s
其 **输出** 如下:
0 a 1 b 2 c 3 d dtype: object
我们没有传递任何 index,因此默认情况下,它分配了从 0 到 **len(data)-1** 的索引,即 0 到 3。
示例 2
#import the pandas library and aliasing as pd import pandas as pd import numpy as np data = np.array(['a','b','c','d']) s = pd.Series(data,index=[100,101,102,103]) print s
其 **输出** 如下:
100 a 101 b 102 c 103 d dtype: object
我们在这里传递了 index 值。现在我们可以在输出中看到自定义的索引值。
从字典创建 Series
可以将 **字典** 作为输入传递,如果未指定 index,则字典键将按排序顺序排列以构建 index。如果传递了 **index**,则将提取与 index 中标签对应的 data 中的值。
示例 1
#import the pandas library and aliasing as pd import pandas as pd import numpy as np data = {'a' : 0., 'b' : 1., 'c' : 2.} s = pd.Series(data) print s
其 **输出** 如下:
a 0.0 b 1.0 c 2.0 dtype: float64
**注意** - 字典键用于构建索引。
示例 2
#import the pandas library and aliasing as pd import pandas as pd import numpy as np data = {'a' : 0., 'b' : 1., 'c' : 2.} s = pd.Series(data,index=['b','c','d','a']) print s
其 **输出** 如下:
b 1.0 c 2.0 d NaN a 0.0 dtype: float64
**注意** - 保留索引顺序,缺失元素用 NaN(非数字)填充。
从标量创建 Series
如果 data 是一个标量值,则必须提供 index。该值将重复以匹配 **index** 的长度
#import the pandas library and aliasing as pd import pandas as pd import numpy as np s = pd.Series(5, index=[0, 1, 2, 3]) print s
其 **输出** 如下:
0 5 1 5 2 5 3 5 dtype: int64
使用位置从 Series 访问数据
序列中的数据可以像访问ndarray一样访问。
示例 1
检索第一个元素。我们已经知道,数组的计数从零开始,这意味着第一个元素存储在第零个位置,以此类推。
import pandas as pd s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e']) #retrieve the first element print s[0]
其 **输出** 如下:
1
示例 2
检索序列中的前三个元素。如果在前面插入一个:,则将提取从该索引开始的所有项。如果使用两个参数(它们之间用:隔开),则提取这两个索引之间的项(不包括停止索引)。
import pandas as pd s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e']) #retrieve the first three element print s[:3]
其 **输出** 如下:
a 1 b 2 c 3 dtype: int64
示例3
检索最后三个元素。
import pandas as pd s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e']) #retrieve the last three element print s[-3:]
其 **输出** 如下:
c 3 d 4 e 5 dtype: int64
使用标签(索引)检索数据
Series类似于固定大小的dict,您可以通过索引标签获取和设置值。
示例 1
使用索引标签值检索单个元素。
import pandas as pd s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e']) #retrieve a single element print s['a']
其 **输出** 如下:
1
示例 2
使用索引标签值的列表检索多个元素。
import pandas as pd s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e']) #retrieve multiple elements print s[['a','c','d']]
其 **输出** 如下:
a 1 c 3 d 4 dtype: int64
示例3
如果标签不存在,则会引发异常。
import pandas as pd s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e']) #retrieve multiple elements print s['f']
其 **输出** 如下:
… KeyError: 'f'
Python Pandas - DataFrame
DataFrame是一个二维数据结构,即数据以表格形式在行和列中对齐。
DataFrame的特征
- 列的类型可能不同
- 大小——可变
- 带标签的轴(行和列)
- 可以对行和列执行算术运算
结构
让我们假设我们正在创建一个包含学生数据的数据框。
您可以将其视为SQL表或电子表格数据表示。
pandas.DataFrame
可以使用以下构造函数创建pandas DataFrame:
pandas.DataFrame( data, index, columns, dtype, copy)
构造函数的参数如下:
序号 | 参数和描述 |
---|---|
1 |
data data采用多种形式,例如ndarray、series、map、列表、dict、常量以及另一个DataFrame。 |
2 |
index 对于行标签,用于结果框架的索引是可选的,如果没有传递索引,则默认为np.arange(n)。 |
3 |
列 对于列标签,可选的默认语法是- np.arange(n)。只有在没有传递索引的情况下才为真。 |
4 |
dtype 每列的数据类型。 |
5 |
copy 此命令(或任何它是什么)用于复制数据,如果默认值为False。 |
创建DataFrame
可以使用各种输入创建pandas DataFrame,例如:
- 列表
- 字典
- Series
- NumPy ndarrays
- 另一个DataFrame
在本章的后续部分,我们将看到如何使用这些输入创建DataFrame。
创建空DataFrame
可以创建的基本DataFrame是一个空DataFrame。
示例
#import the pandas library and aliasing as pd import pandas as pd df = pd.DataFrame() print df
其 **输出** 如下:
Empty DataFrame Columns: [] Index: []
从列表创建DataFrame
可以使用单个列表或列表的列表创建DataFrame。
示例 1
import pandas as pd data = [1,2,3,4,5] df = pd.DataFrame(data) print df
其 **输出** 如下:
0 0 1 1 2 2 3 3 4 4 5
示例 2
import pandas as pd data = [['Alex',10],['Bob',12],['Clarke',13]] df = pd.DataFrame(data,columns=['Name','Age']) print df
其 **输出** 如下:
Name Age 0 Alex 10 1 Bob 12 2 Clarke 13
示例3
import pandas as pd data = [['Alex',10],['Bob',12],['Clarke',13]] df = pd.DataFrame(data,columns=['Name','Age'],dtype=float) print df
其 **输出** 如下:
Name Age 0 Alex 10.0 1 Bob 12.0 2 Clarke 13.0
注意——观察,dtype参数将“年龄”列的类型更改为浮点型。
从ndarray/列表的字典创建DataFrame
所有ndarrays的长度必须相同。如果传递了索引,则索引的长度应等于数组的长度。
如果没有传递索引,则默认情况下,索引将为range(n),其中n为数组长度。
示例 1
import pandas as pd data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]} df = pd.DataFrame(data) print df
其 **输出** 如下:
Age Name 0 28 Tom 1 34 Jack 2 29 Steve 3 42 Ricky
注意——观察值0,1,2,3。它们是使用函数range(n)为每个值分配的默认索引。
示例 2
现在让我们使用数组创建一个带索引的DataFrame。
import pandas as pd data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]} df = pd.DataFrame(data, index=['rank1','rank2','rank3','rank4']) print df
其 **输出** 如下:
Age Name rank1 28 Tom rank2 34 Jack rank3 29 Steve rank4 42 Ricky
注意——观察,index参数为每一行分配一个索引。
从字典列表创建DataFrame
字典列表可以作为输入数据传递来创建DataFrame。字典键默认作为列名。
示例 1
以下示例演示如何通过传递字典列表来创建DataFrame。
import pandas as pd data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}] df = pd.DataFrame(data) print df
其 **输出** 如下:
a b c 0 1 2 NaN 1 5 10 20.0
注意——观察,NaN(非数字)附加在缺失区域。
示例 2
以下示例演示如何通过传递字典列表和行索引来创建DataFrame。
import pandas as pd data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}] df = pd.DataFrame(data, index=['first', 'second']) print df
其 **输出** 如下:
a b c first 1 2 NaN second 5 10 20.0
示例3
以下示例演示如何使用字典列表、行索引和列索引创建DataFrame。
import pandas as pd data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}] #With two column indices, values same as dictionary keys df1 = pd.DataFrame(data, index=['first', 'second'], columns=['a', 'b']) #With two column indices with one index with other name df2 = pd.DataFrame(data, index=['first', 'second'], columns=['a', 'b1']) print df1 print df2
其 **输出** 如下:
#df1 output a b first 1 2 second 5 10 #df2 output a b1 first 1 NaN second 5 NaN
注意——观察,df2 DataFrame是用字典键以外的列索引创建的;因此,在适当的位置附加了NaN。而df1是用与字典键相同的列索引创建的,因此附加了NaN。
从Series的字典创建DataFrame
可以传递Series的字典来形成DataFrame。结果索引是传递的所有Series索引的并集。
示例
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print df
其 **输出** 如下:
one two a 1.0 1 b 2.0 2 c 3.0 3 d NaN 4
注意——观察,对于series one,没有传递标签‘d’,但在结果中,对于d标签,附加了NaN。
现在让我们通过示例了解列选择、添加和删除。
列选择
我们将通过从DataFrame中选择一列来理解这一点。
示例
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print df ['one']
其 **输出** 如下:
a 1.0 b 2.0 c 3.0 d NaN Name: one, dtype: float64
列添加
我们将通过向现有数据框添加新列来理解这一点。
示例
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) # Adding a new column to an existing DataFrame object with column label by passing new series print ("Adding a new column by passing as Series:") df['three']=pd.Series([10,20,30],index=['a','b','c']) print df print ("Adding a new column using the existing columns in DataFrame:") df['four']=df['one']+df['three'] print df
其 **输出** 如下:
Adding a new column by passing as Series: one two three a 1.0 1 10.0 b 2.0 2 20.0 c 3.0 3 30.0 d NaN 4 NaN Adding a new column using the existing columns in DataFrame: one two three four a 1.0 1 10.0 11.0 b 2.0 2 20.0 22.0 c 3.0 3 30.0 33.0 d NaN 4 NaN NaN
列删除
列可以被删除或弹出;让我们举个例子来理解如何操作。
示例
# Using the previous DataFrame, we will delete a column # using del function import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 'three' : pd.Series([10,20,30], index=['a','b','c'])} df = pd.DataFrame(d) print ("Our dataframe is:") print df # using del function print ("Deleting the first column using DEL function:") del df['one'] print df # using pop function print ("Deleting another column using POP function:") df.pop('two') print df
其 **输出** 如下:
Our dataframe is: one three two a 1.0 10.0 1 b 2.0 20.0 2 c 3.0 30.0 3 d NaN NaN 4 Deleting the first column using DEL function: three two a 10.0 1 b 20.0 2 c 30.0 3 d NaN 4 Deleting another column using POP function: three a 10.0 b 20.0 c 30.0 d NaN
行选择、添加和删除
我们现在将通过示例了解行选择、添加和删除。让我们从选择的概念开始。
按标签选择
可以通过将行标签传递给loc函数来选择行。
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print df.loc['b']
其 **输出** 如下:
one 2.0 two 2.0 Name: b, dtype: float64
结果是一个系列,其标签作为DataFrame的列名。并且,该系列的名称是检索它的标签。
按整数位置选择
可以通过将整数位置传递给iloc函数来选择行。
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print df.iloc[2]
其 **输出** 如下:
one 3.0 two 3.0 Name: c, dtype: float64
切片行
可以使用“:”运算符选择多行。
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print df[2:4]
其 **输出** 如下:
one two c 3.0 3 d NaN 4
添加行
使用append函数将新行添加到DataFrame。此函数将在末尾附加行。
import pandas as pd df = pd.DataFrame([[1, 2], [3, 4]], columns = ['a','b']) df2 = pd.DataFrame([[5, 6], [7, 8]], columns = ['a','b']) df = df.append(df2) print df
其 **输出** 如下:
a b 0 1 2 1 3 4 0 5 6 1 7 8
删除行
使用索引标签从DataFrame中删除或删除行。如果标签重复,则将删除多行。
如果您观察到,在上例中,标签是重复的。让我们删除一个标签,看看将删除多少行。
import pandas as pd df = pd.DataFrame([[1, 2], [3, 4]], columns = ['a','b']) df2 = pd.DataFrame([[5, 6], [7, 8]], columns = ['a','b']) df = df.append(df2) # Drop rows with label 0 df = df.drop(0) print df
其 **输出** 如下:
a b 1 3 4 1 7 8
在上例中,删除了两行,因为这两行包含相同的标签0。
Python Pandas - Panel
面板是一个三维数据容器。术语面板数据源于计量经济学,并且部分地决定了pandas的名称——pan(el)-da(ta)-s。
这三个轴的名称旨在为描述涉及面板数据的操作赋予一些语义含义。它们是:
items——轴0,每个项目对应于内部包含的DataFrame。
major_axis——轴1,它是每个DataFrame的索引(行)。
minor_axis——轴2,它是每个DataFrame的列。
pandas.Panel()
可以使用以下构造函数创建面板:
pandas.Panel(data, items, major_axis, minor_axis, dtype, copy)
构造函数的参数如下:
参数 | 描述 |
---|---|
data | 数据采用多种形式,例如ndarray、series、map、列表、dict、常量以及另一个DataFrame |
items | axis=0 |
major_axis | axis=1 |
minor_axis | axis=2 |
dtype | 每列的数据类型 |
copy | 复制数据。默认值,false |
创建面板
可以使用多种方法创建面板,例如:
- 从ndarrays
- 从DataFrame的字典
从3D ndarray
# creating an empty panel import pandas as pd import numpy as np data = np.random.rand(2,4,5) p = pd.Panel(data) print p
其 **输出** 如下:
<class 'pandas.core.panel.Panel'> Dimensions: 2 (items) x 4 (major_axis) x 5 (minor_axis) Items axis: 0 to 1 Major_axis axis: 0 to 3 Minor_axis axis: 0 to 4
注意——观察空面板和上述面板的维度,所有对象都不同。
从DataFrame对象的字典
#creating an empty panel import pandas as pd import numpy as np data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 'Item2' : pd.DataFrame(np.random.randn(4, 2))} p = pd.Panel(data) print p
其 **输出** 如下:
Dimensions: 2 (items) x 4 (major_axis) x 3 (minor_axis) Items axis: Item1 to Item2 Major_axis axis: 0 to 3 Minor_axis axis: 0 to 2
创建空面板
可以使用Panel构造函数创建空面板,如下所示:
#creating an empty panel import pandas as pd p = pd.Panel() print p
其 **输出** 如下:
<class 'pandas.core.panel.Panel'> Dimensions: 0 (items) x 0 (major_axis) x 0 (minor_axis) Items axis: None Major_axis axis: None Minor_axis axis: None
从面板中选择数据
使用以下方法从面板中选择数据:
- Items
- Major_axis
- Minor_axis
使用Items
# creating an empty panel import pandas as pd import numpy as np data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 'Item2' : pd.DataFrame(np.random.randn(4, 2))} p = pd.Panel(data) print p['Item1']
其 **输出** 如下:
0 1 2 0 0.488224 -0.128637 0.930817 1 0.417497 0.896681 0.576657 2 -2.775266 0.571668 0.290082 3 -0.400538 -0.144234 1.110535
我们有两个项目,我们检索了item1。结果是一个DataFrame,具有4行和3列,它们是Major_axis和Minor_axis维度。
使用major_axis
可以使用方法panel.major_axis(index)访问数据。
# creating an empty panel import pandas as pd import numpy as np data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 'Item2' : pd.DataFrame(np.random.randn(4, 2))} p = pd.Panel(data) print p.major_xs(1)
其 **输出** 如下:
Item1 Item2 0 0.417497 0.748412 1 0.896681 -0.557322 2 0.576657 NaN
使用minor_axis
可以使用方法panel.minor_axis(index)访问数据。
# creating an empty panel import pandas as pd import numpy as np data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 'Item2' : pd.DataFrame(np.random.randn(4, 2))} p = pd.Panel(data) print p.minor_xs(1)
其 **输出** 如下:
Item1 Item2 0 -0.128637 -1.047032 1 0.896681 -0.557322 2 0.571668 0.431953 3 -0.144234 1.302466
注意——观察维度的变化。
Python Pandas - 基本功能
到目前为止,我们了解了三种Pandas数据结构以及如何创建它们。由于DataFrame在实时数据处理中的重要性,我们将主要关注DataFrame对象,并讨论其他一些数据结构。
Series基本功能
序号 | 属性或方法和描述 |
---|---|
1 |
axes 返回行轴标签的列表 |
2 |
dtype 返回对象的dtype。 |
3 |
empty 如果Series为空,则返回True。 |
4 |
ndim 返回底层数据的维度数,定义为1。 |
5 |
size 返回底层数据中的元素数。 |
6 |
values 将Series作为ndarray返回。 |
7 |
head() 返回前n行。 |
8 |
tail() 返回最后n行。 |
现在让我们创建一个Series,看看上面所有表格化的属性操作。
示例
import pandas as pd import numpy as np #Create a series with 100 random numbers s = pd.Series(np.random.randn(4)) print s
其 **输出** 如下:
0 0.967853 1 -0.148368 2 -1.395906 3 -1.758394 dtype: float64
axes
返回Series标签的列表。
import pandas as pd import numpy as np #Create a series with 100 random numbers s = pd.Series(np.random.randn(4)) print ("The axes are:") print s.axes
其 **输出** 如下:
The axes are: [RangeIndex(start=0, stop=4, step=1)]
上述结果是从0到5的值列表的紧凑格式,即[0,1,2,3,4]。
empty
返回布尔值,表示对象是否为空;True表示对象为空。
import pandas as pd import numpy as np #Create a series with 100 random numbers s = pd.Series(np.random.randn(4)) print ("Is the Object empty?") print s.empty
其 **输出** 如下:
Is the Object empty? False
ndim
返回对象的维度数。根据定义,Series是一维数据结构,因此它返回
import pandas as pd import numpy as np #Create a series with 4 random numbers s = pd.Series(np.random.randn(4)) print s print ("The dimensions of the object:") print s.ndim
其 **输出** 如下:
0 0.175898 1 0.166197 2 -0.609712 3 -1.377000 dtype: float64 The dimensions of the object: 1
size
返回Series的大小(长度)。
import pandas as pd import numpy as np #Create a series with 4 random numbers s = pd.Series(np.random.randn(2)) print s print ("The size of the object:") print s.size
其 **输出** 如下:
0 3.078058 1 -1.207803 dtype: float64 The size of the object: 2
values
将Series中的实际数据作为数组返回。
import pandas as pd import numpy as np #Create a series with 4 random numbers s = pd.Series(np.random.randn(4)) print s print ("The actual data series is:") print s.values
其 **输出** 如下:
0 1.787373 1 -0.605159 2 0.180477 3 -0.140922 dtype: float64 The actual data series is: [ 1.78737302 -0.60515881 0.18047664 -0.1409218 ]
Head & Tail
要查看Series或DataFrame对象的小样本,请使用head()和tail()方法。
head()返回前n行(观察索引值)。要显示的元素默认数量为五个,但您可以传递自定义数量。
import pandas as pd import numpy as np #Create a series with 4 random numbers s = pd.Series(np.random.randn(4)) print ("The original series is:") print s print ("The first two rows of the data series:") print s.head(2)
其 **输出** 如下:
The original series is: 0 0.720876 1 -0.765898 2 0.479221 3 -0.139547 dtype: float64 The first two rows of the data series: 0 0.720876 1 -0.765898 dtype: float64
tail()返回最后n行(观察索引值)。要显示的元素默认数量为五个,但您可以传递自定义数量。
import pandas as pd import numpy as np #Create a series with 4 random numbers s = pd.Series(np.random.randn(4)) print ("The original series is:") print s print ("The last two rows of the data series:") print s.tail(2)
其 **输出** 如下:
The original series is: 0 -0.655091 1 -0.881407 2 -0.608592 3 -2.341413 dtype: float64 The last two rows of the data series: 2 -0.608592 3 -2.341413 dtype: float64
DataFrame基本功能
现在让我们了解什么是DataFrame基本功能。下表列出了有助于DataFrame基本功能的重要属性或方法。
序号 | 属性或方法和描述 |
---|---|
1 |
T 转置行和列。 |
2 |
axes 返回一个列表,其中仅包含行轴标签和列轴标签作为成员。 |
3 |
dtypes 返回此对象中的dtypes。 |
4 |
empty 如果NDFrame完全为空[没有项目];如果任何轴的长度为0,则为True。 |
5 |
ndim 轴/数组维数。 |
6 |
shape 返回表示DataFrame维度的元组。 |
7 |
size NDFrame中的元素数。 |
8 |
values NDFrame的NumPy表示。 |
9 |
head() 返回前n行。 |
10 |
tail() 返回最后n行。 |
现在让我们创建一个DataFrame,看看上面提到的所有属性是如何操作的。
示例
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Our data series is:") print df
其 **输出** 如下:
Our data series is: Age Name Rating 0 25 Tom 4.23 1 26 James 3.24 2 25 Ricky 3.98 3 23 Vin 2.56 4 30 Steve 3.20 5 29 Smith 4.60 6 23 Jack 3.80
T(转置)
返回DataFrame的转置。行和列将互换。
import pandas as pd import numpy as np # Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} # Create a DataFrame df = pd.DataFrame(d) print ("The transpose of the data series is:") print df.T
其 **输出** 如下:
The transpose of the data series is: 0 1 2 3 4 5 6 Age 25 26 25 23 30 29 23 Name Tom James Ricky Vin Steve Smith Jack Rating 4.23 3.24 3.98 2.56 3.2 4.6 3.8
axes
返回行轴标签和列轴标签的列表。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Row axis labels and column axis labels are:") print df.axes
其 **输出** 如下:
Row axis labels and column axis labels are: [RangeIndex(start=0, stop=7, step=1), Index([u'Age', u'Name', u'Rating'], dtype='object')]
dtypes
返回每一列的数据类型。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("The data types of each column are:") print df.dtypes
其 **输出** 如下:
The data types of each column are: Age int64 Name object Rating float64 dtype: object
empty
返回布尔值,表示对象是否为空;True表示对象为空。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Is the object empty?") print df.empty
其 **输出** 如下:
Is the object empty? False
ndim
返回对象的维度数。根据定义,DataFrame是一个二维对象。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Our object is:") print df print ("The dimension of the object is:") print df.ndim
其 **输出** 如下:
Our object is: Age Name Rating 0 25 Tom 4.23 1 26 James 3.24 2 25 Ricky 3.98 3 23 Vin 2.56 4 30 Steve 3.20 5 29 Smith 4.60 6 23 Jack 3.80 The dimension of the object is: 2
shape
返回一个元组,表示 DataFrame 的维度。元组 (a,b),其中 a 表示行数,b 表示列数。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Our object is:") print df print ("The shape of the object is:") print df.shape
其 **输出** 如下:
Our object is: Age Name Rating 0 25 Tom 4.23 1 26 James 3.24 2 25 Ricky 3.98 3 23 Vin 2.56 4 30 Steve 3.20 5 29 Smith 4.60 6 23 Jack 3.80 The shape of the object is: (7, 3)
size
返回 DataFrame 中元素的个数。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Our object is:") print df print ("The total number of elements in our object is:") print df.size
其 **输出** 如下:
Our object is: Age Name Rating 0 25 Tom 4.23 1 26 James 3.24 2 25 Ricky 3.98 3 23 Vin 2.56 4 30 Steve 3.20 5 29 Smith 4.60 6 23 Jack 3.80 The total number of elements in our object is: 21
values
将 DataFrame 中的实际数据作为NDarray返回。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Our object is:") print df print ("The actual data in our data frame is:") print df.values
其 **输出** 如下:
Our object is: Age Name Rating 0 25 Tom 4.23 1 26 James 3.24 2 25 Ricky 3.98 3 23 Vin 2.56 4 30 Steve 3.20 5 29 Smith 4.60 6 23 Jack 3.80 The actual data in our data frame is: [[25 'Tom' 4.23] [26 'James' 3.24] [25 'Ricky' 3.98] [23 'Vin' 2.56] [30 'Steve' 3.2] [29 'Smith' 4.6] [23 'Jack' 3.8]]
Head & Tail
要查看 DataFrame 对象的小样本,可以使用head()和 tail() 方法。head()返回前n行(观察索引值)。默认显示的元素个数为五个,但您可以传递自定义个数。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Our data frame is:") print df print ("The first two rows of the data frame is:") print df.head(2)
其 **输出** 如下:
Our data frame is: Age Name Rating 0 25 Tom 4.23 1 26 James 3.24 2 25 Ricky 3.98 3 23 Vin 2.56 4 30 Steve 3.20 5 29 Smith 4.60 6 23 Jack 3.80 The first two rows of the data frame is: Age Name Rating 0 25 Tom 4.23 1 26 James 3.24
tail()返回最后n行(观察索引值)。默认显示的元素个数为五个,但您可以传递自定义个数。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack']), 'Age':pd.Series([25,26,25,23,30,29,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #Create a DataFrame df = pd.DataFrame(d) print ("Our data frame is:") print df print ("The last two rows of the data frame is:") print df.tail(2)
其 **输出** 如下:
Our data frame is: Age Name Rating 0 25 Tom 4.23 1 26 James 3.24 2 25 Ricky 3.98 3 23 Vin 2.56 4 30 Steve 3.20 5 29 Smith 4.60 6 23 Jack 3.80 The last two rows of the data frame is: Age Name Rating 5 29 Smith 4.6 6 23 Jack 3.8
Python Pandas - 描述性统计
许多方法共同计算 DataFrame 的描述性统计和其他相关操作。大多数是聚合函数,例如sum(),mean(),但有些函数,例如sumsum(),会生成相同大小的对象。一般来说,这些方法都接受一个axis参数,就像ndarray.{sum, std, ...}一样,但是轴可以由名称或整数指定。
DataFrame − “index”(axis=0,默认),“columns”(axis=1)
让我们创建一个 DataFrame,并在本章中使用此对象进行所有操作。
示例
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack', 'Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } #Create a DataFrame df = pd.DataFrame(d) print df
其 **输出** 如下:
Age Name Rating 0 25 Tom 4.23 1 26 James 3.24 2 25 Ricky 3.98 3 23 Vin 2.56 4 30 Steve 3.20 5 29 Smith 4.60 6 23 Jack 3.80 7 34 Lee 3.78 8 40 David 2.98 9 30 Gasper 4.80 10 51 Betina 4.10 11 46 Andres 3.65
sum()
返回请求轴的值之和。默认情况下,轴为索引 (axis=0)。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack', 'Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } #Create a DataFrame df = pd.DataFrame(d) print df.sum()
其 **输出** 如下:
Age 382 Name TomJamesRickyVinSteveSmithJackLeeDavidGasperBe... Rating 44.92 dtype: object
每列分别相加(字符串被追加)。
axis=1
此语法将给出如下所示的输出。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack', 'Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } #Create a DataFrame df = pd.DataFrame(d) print df.sum(1)
其 **输出** 如下:
0 29.23 1 29.24 2 28.98 3 25.56 4 33.20 5 33.60 6 26.80 7 37.78 8 42.98 9 34.80 10 55.10 11 49.65 dtype: float64
mean()
返回平均值。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack', 'Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } #Create a DataFrame df = pd.DataFrame(d) print df.mean()
其 **输出** 如下:
Age 31.833333 Rating 3.743333 dtype: float64
std()
返回数值列的贝塞尔标准差。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack', 'Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } #Create a DataFrame df = pd.DataFrame(d) print df.std()
其 **输出** 如下:
Age 9.232682 Rating 0.661628 dtype: float64
函数与说明
现在让我们了解 Python Pandas 中描述性统计下的函数。下表列出了重要的函数:
序号 | 函数 | 描述 |
---|---|---|
1 | count() | 非空观察值的个数 |
2 | sum() | 值的总和 |
3 | mean() | 值的平均值 |
4 | median() | 值的中位数 |
5 | mode() | 值的众数 |
6 | std() | 值的标准差 |
7 | min() | 最小值 |
8 | max() | 最大值 |
9 | abs() | 绝对值 |
10 | prod() | 值的乘积 |
11 | cumsum() | 累积和 |
12 | cumprod() | 累积乘积 |
注意 − 由于 DataFrame 是异构数据结构,通用操作并不适用于所有函数。
像sum(),cumsum()这样的函数可以处理数值和字符(或)字符串数据元素,而不会出现任何错误。尽管在实践中,字符聚合通常不被使用,但这些函数不会抛出任何异常。
像abs(),cumprod()这样的函数在 DataFrame 包含字符或字符串数据时会抛出异常,因为无法执行此类操作。
数据汇总
describe()函数计算与 DataFrame 列相关的统计摘要。
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack', 'Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } #Create a DataFrame df = pd.DataFrame(d) print df.describe()
其 **输出** 如下:
Age Rating count 12.000000 12.000000 mean 31.833333 3.743333 std 9.232682 0.661628 min 23.000000 2.560000 25% 25.000000 3.230000 50% 29.500000 3.790000 75% 35.500000 4.132500 max 51.000000 4.800000
此函数给出mean、std和IQR值。并且,该函数排除字符列并给出关于数值列的摘要。'include' 是一个参数,用于传递有关需要考虑哪些列进行汇总的必要信息。接受值列表;默认为 'number'。
- object − 汇总字符串列
- number − 汇总数值列
- all − 汇总所有列(不应将其作为列表值传递)
现在,在程序中使用以下语句并检查输出:
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack', 'Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } #Create a DataFrame df = pd.DataFrame(d) print df.describe(include=['object'])
其 **输出** 如下:
Name count 12 unique 12 top Ricky freq 1
现在,使用以下语句并检查输出:
import pandas as pd import numpy as np #Create a Dictionary of series d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Smith','Jack', 'Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } #Create a DataFrame df = pd.DataFrame(d) print df. describe(include='all')
其 **输出** 如下:
Age Name Rating count 12.000000 12 12.000000 unique NaN 12 NaN top NaN Ricky NaN freq NaN 1 NaN mean 31.833333 NaN 3.743333 std 9.232682 NaN 0.661628 min 23.000000 NaN 2.560000 25% 25.000000 NaN 3.230000 50% 29.500000 NaN 3.790000 75% 35.500000 NaN 4.132500 max 51.000000 NaN 4.800000
Python Pandas - 函数应用
要将您自己或其他库的函数应用于 Pandas 对象,您应该了解三个重要的方法。以下讨论了这些方法。要使用的方法取决于您的函数是否期望对整个 DataFrame、行或列方式或元素方式进行操作。
- 表级函数应用:pipe()
- 行或列级函数应用:apply()
- 元素级函数应用:applymap()
表级函数应用
可以通过传递函数和适当数量的参数作为 pipe 参数来执行自定义操作。因此,操作是在整个 DataFrame 上执行的。
例如,将值 2 加到 DataFrame 中的所有元素。然后,
adder 函数
adder 函数将两个数值作为参数相加并返回和。
def adder(ele1,ele2): return ele1+ele2
我们现在将使用自定义函数对 DataFrame 进行操作。
df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3']) df.pipe(adder,2)
让我们看看完整的程序:
import pandas as pd import numpy as np def adder(ele1,ele2): return ele1+ele2 df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3']) df.pipe(adder,2) print df.apply(np.mean)
其 **输出** 如下:
col1 col2 col3 0 2.176704 2.219691 1.509360 1 2.222378 2.422167 3.953921 2 2.241096 1.135424 2.696432 3 2.355763 0.376672 1.182570 4 2.308743 2.714767 2.130288
行或列级函数应用
可以使用apply()方法沿 DataFrame 或 Panel 的轴应用任意函数,该方法与描述性统计方法一样,接受可选的 axis 参数。默认情况下,操作按列执行,将每一列作为类数组处理。
示例 1
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3']) df.apply(np.mean) print df.apply(np.mean)
其 **输出** 如下:
col1 -0.288022 col2 1.044839 col3 -0.187009 dtype: float64
通过传递axis参数,可以按行执行操作。
示例 2
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3']) df.apply(np.mean,axis=1) print df.apply(np.mean)
其 **输出** 如下:
col1 0.034093 col2 -0.152672 col3 -0.229728 dtype: float64
示例3
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3']) df.apply(lambda x: x.max() - x.min()) print df.apply(np.mean)
其 **输出** 如下:
col1 -0.167413 col2 -0.370495 col3 -0.707631 dtype: float64
元素级函数应用
并非所有函数都可以向量化(既不是返回另一个数组的 NumPy 数组,也不是任何值),DataFrame 上的applymap()方法和Series上的analogously map()方法接受任何接受单个值并返回单个值的 Python 函数。
示例 1
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3']) # My custom function df['col1'].map(lambda x:x*100) print df.apply(np.mean)
其 **输出** 如下:
col1 0.480742 col2 0.454185 col3 0.266563 dtype: float64
示例 2
import pandas as pd import numpy as np # My custom function df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3']) df.applymap(lambda x:x*100) print df.apply(np.mean)
其 **输出** 如下:
col1 0.395263 col2 0.204418 col3 -0.795188 dtype: float64
Python Pandas - 重新索引
重新索引更改 DataFrame 的行标签和列标签。重新索引意味着使数据符合特定轴上给定标签集。
可以通过索引完成多个操作,例如:
重新排序现有数据以匹配新的标签集。
在标签位置插入缺失值 (NA) 标记,这些位置不存在该标签的数据。
示例
import pandas as pd import numpy as np N=20 df = pd.DataFrame({ 'A': pd.date_range(start='2016-01-01',periods=N,freq='D'), 'x': np.linspace(0,stop=N-1,num=N), 'y': np.random.rand(N), 'C': np.random.choice(['Low','Medium','High'],N).tolist(), 'D': np.random.normal(100, 10, size=(N)).tolist() }) #reindex the DataFrame df_reindexed = df.reindex(index=[0,2,5], columns=['A', 'C', 'B']) print df_reindexed
其 **输出** 如下:
A C B 0 2016-01-01 Low NaN 2 2016-01-03 High NaN 5 2016-01-06 Low NaN
与其他对象对齐重新索引
您可能希望获取一个对象并将其轴重新索引为与另一个对象相同的标签。考虑以下示例以了解相同内容。
示例
import pandas as pd import numpy as np df1 = pd.DataFrame(np.random.randn(10,3),columns=['col1','col2','col3']) df2 = pd.DataFrame(np.random.randn(7,3),columns=['col1','col2','col3']) df1 = df1.reindex_like(df2) print df1
其 **输出** 如下:
col1 col2 col3 0 -2.467652 -1.211687 -0.391761 1 -0.287396 0.522350 0.562512 2 -0.255409 -0.483250 1.866258 3 -1.150467 -0.646493 -0.222462 4 0.152768 -2.056643 1.877233 5 -1.155997 1.528719 -1.343719 6 -1.015606 -1.245936 -0.295275
注意 − 在这里,df1 DataFrame 被更改并像df2一样重新索引。列名应该匹配,否则整个列标签将添加 NAN。
重新索引时的填充
reindex()接受一个可选参数 method,它是一个填充方法,其值如下:
pad/ffill − 向前填充值
bfill/backfill − 向后填充值
nearest − 从最近的索引值填充
示例
import pandas as pd import numpy as np df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3']) df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3']) # Padding NAN's print df2.reindex_like(df1) # Now Fill the NAN's with preceding Values print ("Data Frame with Forward Fill:") print df2.reindex_like(df1,method='ffill')
其 **输出** 如下:
col1 col2 col3 0 1.311620 -0.707176 0.599863 1 -0.423455 -0.700265 1.133371 2 NaN NaN NaN 3 NaN NaN NaN 4 NaN NaN NaN 5 NaN NaN NaN Data Frame with Forward Fill: col1 col2 col3 0 1.311620 -0.707176 0.599863 1 -0.423455 -0.700265 1.133371 2 -0.423455 -0.700265 1.133371 3 -0.423455 -0.700265 1.133371 4 -0.423455 -0.700265 1.133371 5 -0.423455 -0.700265 1.133371
注意 − 最后四行已填充。
重新索引时的填充限制
limit 参数提供了对重新索引时填充的额外控制。Limit 指定连续匹配的最大计数。让我们考虑以下示例以了解相同内容:
示例
import pandas as pd import numpy as np df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3']) df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3']) # Padding NAN's print df2.reindex_like(df1) # Now Fill the NAN's with preceding Values print ("Data Frame with Forward Fill limiting to 1:") print df2.reindex_like(df1,method='ffill',limit=1)
其 **输出** 如下:
col1 col2 col3 0 0.247784 2.128727 0.702576 1 -0.055713 -0.021732 -0.174577 2 NaN NaN NaN 3 NaN NaN NaN 4 NaN NaN NaN 5 NaN NaN NaN Data Frame with Forward Fill limiting to 1: col1 col2 col3 0 0.247784 2.128727 0.702576 1 -0.055713 -0.021732 -0.174577 2 -0.055713 -0.021732 -0.174577 3 NaN NaN NaN 4 NaN NaN NaN 5 NaN NaN NaN
注意 − 请注意,只有第 7 行由前面的第 6 行填充。然后,其余行保持不变。
重命名
rename() 方法允许您根据某些映射(字典或 Series)或任意函数重新标记轴。
让我们考虑以下示例来理解这一点:
import pandas as pd import numpy as np df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3']) print df1 print ("After renaming the rows and columns:") print df1.rename(columns={'col1' : 'c1', 'col2' : 'c2'}, index = {0 : 'apple', 1 : 'banana', 2 : 'durian'})
其 **输出** 如下:
col1 col2 col3 0 0.486791 0.105759 1.540122 1 -0.990237 1.007885 -0.217896 2 -0.483855 -1.645027 -1.194113 3 -0.122316 0.566277 -0.366028 4 -0.231524 -0.721172 -0.112007 5 0.438810 0.000225 0.435479 After renaming the rows and columns: c1 c2 col3 apple 0.486791 0.105759 1.540122 banana -0.990237 1.007885 -0.217896 durian -0.483855 -1.645027 -1.194113 3 -0.122316 0.566277 -0.366028 4 -0.231524 -0.721172 -0.112007 5 0.438810 0.000225 0.435479
rename() 方法提供一个inplace命名参数,默认情况下为 False 并复制底层数据。传递inplace=True以就地重命名数据。
Python Pandas - 迭代
对 Pandas 对象的基本迭代的行为取决于类型。当迭代 Series 时,它被视为类数组,基本迭代产生值。其他数据结构,如 DataFrame 和 Panel,遵循在对象的键上迭代的类字典约定。
简而言之,基本迭代(对于对象中的i)产生:
Series − 值
DataFrame − 列标签
Panel − 项目标签
迭代 DataFrame
迭代 DataFrame 会给出列名。让我们考虑以下示例来了解相同内容。
import pandas as pd import numpy as np N=20 df = pd.DataFrame({ 'A': pd.date_range(start='2016-01-01',periods=N,freq='D'), 'x': np.linspace(0,stop=N-1,num=N), 'y': np.random.rand(N), 'C': np.random.choice(['Low','Medium','High'],N).tolist(), 'D': np.random.normal(100, 10, size=(N)).tolist() }) for col in df: print col
其 **输出** 如下:
A C D x y
要迭代 DataFrame 的行,我们可以使用以下函数:
iteritems() − 迭代 (键,值) 对
iterrows() − 将行迭代为 (索引,序列) 对
itertuples() − 将行迭代为命名元组
iteritems()
将每一列迭代为键值对,标签作为键,列值作为 Series 对象。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(4,3),columns=['col1','col2','col3']) for key,value in df.iteritems(): print key,value
其 **输出** 如下:
col1 0 0.802390 1 0.324060 2 0.256811 3 0.839186 Name: col1, dtype: float64 col2 0 1.624313 1 -1.033582 2 1.796663 3 1.856277 Name: col2, dtype: float64 col3 0 -0.022142 1 -0.230820 2 1.160691 3 -0.830279 Name: col3, dtype: float64
观察,每一列都作为 Series 中的键值对单独迭代。
iterrows()
iterrows() 返回迭代器,生成每个索引值以及包含每一行数据的序列。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3']) for row_index,row in df.iterrows(): print row_index,row
其 **输出** 如下:
0 col1 1.529759 col2 0.762811 col3 -0.634691 Name: 0, dtype: float64 1 col1 -0.944087 col2 1.420919 col3 -0.507895 Name: 1, dtype: float64 2 col1 -0.077287 col2 -0.858556 col3 -0.663385 Name: 2, dtype: float64 3 col1 -1.638578 col2 0.059866 col3 0.493482 Name: 3, dtype: float64
注意 − 因为iterrows()迭代行,所以它不会保留跨行的数 据类型。0,1,2 是行索引,col1,col2,col3 是列索引。
itertuples()
itertuples() 方法将返回一个迭代器,为 DataFrame 中的每一行生成一个命名元组。元组的第一个元素将是行的相应索引值,其余值是行值。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3']) for row in df.itertuples(): print row
其 **输出** 如下:
Pandas(Index=0, col1=1.5297586201375899, col2=0.76281127433814944, col3=- 0.6346908238310438) Pandas(Index=1, col1=-0.94408735763808649, col2=1.4209186418359423, col3=- 0.50789517967096232) Pandas(Index=2, col1=-0.07728664756791935, col2=-0.85855574139699076, col3=- 0.6633852507207626) Pandas(Index=3, col1=0.65734942534106289, col2=-0.95057710432604969, col3=0.80344487462316527)
注意 − 迭代时不要尝试修改任何对象。迭代旨在用于读取,迭代器返回原始对象的副本(视图),因此更改不会反映在原始对象上。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3']) for index, row in df.iterrows(): row['a'] = 10 print df
其 **输出** 如下:
col1 col2 col3 0 -1.739815 0.735595 -0.295589 1 0.635485 0.106803 1.527922 2 -0.939064 0.547095 0.038585 3 -1.016509 -0.116580 -0.523158
观察,没有反映任何变化。
Python Pandas - 排序
Pandas 中有两种排序方式。它们是:
- 按标签
- 按实际值
让我们考虑一个带有输出的示例。
import pandas as pd import numpy as np unsorted_df=pd.DataFrame(np.random.randn(10,2),index=[1,4,6,2,3,5,9,8,0,7],colu mns=['col2','col1']) print unsorted_df
其 **输出** 如下:
col2 col1 1 -2.063177 0.537527 4 0.142932 -0.684884 6 0.012667 -0.389340 2 -0.548797 1.848743 3 -1.044160 0.837381 5 0.385605 1.300185 9 1.031425 -1.002967 8 -0.407374 -0.435142 0 2.237453 -1.067139 7 -1.445831 -1.701035
在unsorted_df中,标签和值未排序。让我们看看如何对这些进行排序。
按标签
使用sort_index()方法,通过传递轴参数和排序顺序,可以对 DataFrame 进行排序。默认情况下,按升序对行标签进行排序。
import pandas as pd import numpy as np unsorted_df = pd.DataFrame(np.random.randn(10,2),index=[1,4,6,2,3,5,9,8,0,7],colu mns = ['col2','col1']) sorted_df=unsorted_df.sort_index() print sorted_df
其 **输出** 如下:
col2 col1 0 0.208464 0.627037 1 0.641004 0.331352 2 -0.038067 -0.464730 3 -0.638456 -0.021466 4 0.014646 -0.737438 5 -0.290761 -1.669827 6 -0.797303 -0.018737 7 0.525753 1.628921 8 -0.567031 0.775951 9 0.060724 -0.322425
排序顺序
通过向 ascending 参数传递布尔值,可以控制排序顺序。让我们考虑以下示例以了解相同内容。
import pandas as pd import numpy as np unsorted_df = pd.DataFrame(np.random.randn(10,2),index=[1,4,6,2,3,5,9,8,0,7],colu mns = ['col2','col1']) sorted_df = unsorted_df.sort_index(ascending=False) print sorted_df
其 **输出** 如下:
col2 col1 9 0.825697 0.374463 8 -1.699509 0.510373 7 -0.581378 0.622958 6 -0.202951 0.954300 5 -1.289321 -1.551250 4 1.302561 0.851385 3 -0.157915 -0.388659 2 -1.222295 0.166609 1 0.584890 -0.291048 0 0.668444 -0.061294
排序列
通过传递值为 0 或 1 的轴参数,可以对列标签进行排序。默认情况下,axis=0,按行排序。让我们考虑以下示例以了解相同内容。
import pandas as pd import numpy as np unsorted_df = pd.DataFrame(np.random.randn(10,2),index=[1,4,6,2,3,5,9,8,0,7],colu mns = ['col2','col1']) sorted_df=unsorted_df.sort_index(axis=1) print sorted_df
其 **输出** 如下:
col1 col2 1 -0.291048 0.584890 4 0.851385 1.302561 6 0.954300 -0.202951 2 0.166609 -1.222295 3 -0.388659 -0.157915 5 -1.551250 -1.289321 9 0.374463 0.825697 8 0.510373 -1.699509 0 -0.061294 0.668444 7 0.622958 -0.581378
按值
与索引排序类似,sort_values()是按值排序的方法。它接受一个 'by' 参数,该参数将使用 DataFrame 的列名来排序值。
import pandas as pd import numpy as np unsorted_df = pd.DataFrame({'col1':[2,1,1,1],'col2':[1,3,2,4]}) sorted_df = unsorted_df.sort_values(by='col1') print sorted_df
其 **输出** 如下:
col1 col2 1 1 3 2 1 2 3 1 4 0 2 1
观察,col1 值已排序,相应的 col2 值和行索引将与 col1 一起更改。因此,它们看起来未排序。
'by' 参数接受列值的列表。
import pandas as pd import numpy as np unsorted_df = pd.DataFrame({'col1':[2,1,1,1],'col2':[1,3,2,4]}) sorted_df = unsorted_df.sort_values(by=['col1','col2']) print sorted_df
其 **输出** 如下:
col1 col2 2 1 2 1 1 3 3 1 4 0 2 1
排序算法
sort_values()提供了一个从 mergesort、heapsort 和 quicksort 中选择算法的规定。Mergesort 是唯一稳定的算法。
import pandas as pd import numpy as np unsorted_df = pd.DataFrame({'col1':[2,1,1,1],'col2':[1,3,2,4]}) sorted_df = unsorted_df.sort_values(by='col1' ,kind='mergesort') print sorted_df
其 **输出** 如下:
col1 col2 1 1 3 2 1 2 3 1 4 0 2 1
Python Pandas - 使用文本数据
在本章中,我们将讨论使用我们的基本 Series/Index 的字符串操作。在后续章节中,我们将学习如何在 DataFrame 上应用这些字符串函数。
Pandas 提供了一组字符串函数,使操作字符串数据变得容易。最重要的是,这些函数忽略(或排除)缺失/NaN 值。
几乎所有这些方法都与 Python 字符串函数一起使用(参考:https://docs.pythonlang.cn/3/library/stdtypes.html#string-methods)。因此,将 Series 对象转换为 String 对象,然后执行操作。
现在让我们看看每个操作是如何执行的。
序号 | 函数与说明 |
---|---|
1 |
lower() 将 Series/Index 中的字符串转换为小写。 |
2 |
upper() 将 Series/Index 中的字符串转换为大写。 |
3 |
len() 计算字符串长度。 |
4 |
strip() 用于去除Series/索引中每个字符串两侧的空格(包括换行符)。 |
5 |
split(' ') 使用给定的模式分割每个字符串。 |
6 |
cat(sep=' ') 使用给定的分隔符连接Series/索引元素。 |
7 |
get_dummies() 返回包含独热编码值的DataFrame。 |
8 |
contains(pattern) 如果元素包含子字符串,则为每个元素返回布尔值True,否则返回False。 |
9 |
replace(a,b) 将值a替换为值b。 |
10 |
repeat(value) 将每个元素重复指定次数。 |
11 |
count(pattern) 返回每个元素中模式出现的次数。 |
12 |
startswith(pattern) 如果Series/索引中的元素以该模式开头,则返回True。 |
13 |
endswith(pattern) 如果Series/索引中的元素以该模式结尾,则返回True。 |
14 |
find(pattern) 返回模式第一次出现的第一个位置。 |
15 |
findall(pattern) 返回模式所有出现位置的列表。 |
16 |
swapcase 交换大小写(小写变大写,大写变小写)。 |
17 |
islower() 检查Series/索引中每个字符串中的所有字符是否都小写。返回布尔值。 |
18 |
isupper() 检查Series/索引中每个字符串中的所有字符是否都大写。返回布尔值。 |
19 |
isnumeric() 检查Series/索引中每个字符串中的所有字符是否都是数字。返回布尔值。 |
现在让我们创建一个Series,看看以上所有函数是如何工作的。
import pandas as pd import numpy as np s = pd.Series(['Tom', 'William Rick', 'John', 'Alber@t', np.nan, '1234','SteveSmith']) print s
其 **输出** 如下:
0 Tom 1 William Rick 2 John 3 Alber@t 4 NaN 5 1234 6 Steve Smith dtype: object
lower()
import pandas as pd import numpy as np s = pd.Series(['Tom', 'William Rick', 'John', 'Alber@t', np.nan, '1234','SteveSmith']) print s.str.lower()
其 **输出** 如下:
0 tom 1 william rick 2 john 3 alber@t 4 NaN 5 1234 6 steve smith dtype: object
upper()
import pandas as pd import numpy as np s = pd.Series(['Tom', 'William Rick', 'John', 'Alber@t', np.nan, '1234','SteveSmith']) print s.str.upper()
其 **输出** 如下:
0 TOM 1 WILLIAM RICK 2 JOHN 3 ALBER@T 4 NaN 5 1234 6 STEVE SMITH dtype: object
len()
import pandas as pd import numpy as np s = pd.Series(['Tom', 'William Rick', 'John', 'Alber@t', np.nan, '1234','SteveSmith']) print s.str.len()
其 **输出** 如下:
0 3.0 1 12.0 2 4.0 3 7.0 4 NaN 5 4.0 6 10.0 dtype: float64
strip()
import pandas as pd import numpy as np s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s print ("After Stripping:") print s.str.strip()
其 **输出** 如下:
0 Tom 1 William Rick 2 John 3 Alber@t dtype: object After Stripping: 0 Tom 1 William Rick 2 John 3 Alber@t dtype: object
split(pattern)
import pandas as pd import numpy as np s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s print ("Split Pattern:") print s.str.split(' ')
其 **输出** 如下:
0 Tom 1 William Rick 2 John 3 Alber@t dtype: object Split Pattern: 0 [Tom, , , , , , , , , , ] 1 [, , , , , William, Rick] 2 [John] 3 [Alber@t] dtype: object
cat(sep=pattern)
import pandas as pd import numpy as np s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s.str.cat(sep='_')
其 **输出** 如下:
Tom _ William Rick_John_Alber@t
get_dummies()
import pandas as pd import numpy as np s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s.str.get_dummies()
其 **输出** 如下:
William Rick Alber@t John Tom 0 0 0 0 1 1 1 0 0 0 2 0 0 1 0 3 0 1 0 0
contains ()
import pandas as pd s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s.str.contains(' ')
其 **输出** 如下:
0 True 1 True 2 False 3 False dtype: bool
replace(a,b)
import pandas as pd s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s print ("After replacing @ with $:") print s.str.replace('@','$')
其 **输出** 如下:
0 Tom 1 William Rick 2 John 3 Alber@t dtype: object After replacing @ with $: 0 Tom 1 William Rick 2 John 3 Alber$t dtype: object
repeat(value)
import pandas as pd s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s.str.repeat(2)
其 **输出** 如下:
0 Tom Tom 1 William Rick William Rick 2 JohnJohn 3 Alber@tAlber@t dtype: object
count(pattern)
import pandas as pd s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print ("The number of 'm's in each string:") print s.str.count('m')
其 **输出** 如下:
The number of 'm's in each string: 0 1 1 1 2 0 3 0
startswith(pattern)
import pandas as pd s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print ("Strings that start with 'T':") print s.str. startswith ('T')
其 **输出** 如下:
0 True 1 False 2 False 3 False dtype: bool
endswith(pattern)
import pandas as pd s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print ("Strings that end with 't':") print s.str.endswith('t')
其 **输出** 如下:
Strings that end with 't': 0 False 1 False 2 False 3 True dtype: bool
find(pattern)
import pandas as pd s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s.str.find('e')
其 **输出** 如下:
0 -1 1 -1 2 -1 3 3 dtype: int64
“-1”表示元素中不存在此模式。
findall(pattern)
import pandas as pd s = pd.Series(['Tom ', ' William Rick', 'John', 'Alber@t']) print s.str.findall('e')
其 **输出** 如下:
0 [] 1 [] 2 [] 3 [e] dtype: object
空列表([])表示元素中不存在此模式。
swapcase()
import pandas as pd s = pd.Series(['Tom', 'William Rick', 'John', 'Alber@t']) print s.str.swapcase()
其 **输出** 如下:
0 tOM 1 wILLIAM rICK 2 jOHN 3 aLBER@T dtype: object
islower()
import pandas as pd s = pd.Series(['Tom', 'William Rick', 'John', 'Alber@t']) print s.str.islower()
其 **输出** 如下:
0 False 1 False 2 False 3 False dtype: bool
isupper()
import pandas as pd s = pd.Series(['Tom', 'William Rick', 'John', 'Alber@t']) print s.str.isupper()
其 **输出** 如下:
0 False 1 False 2 False 3 False dtype: bool
isnumeric()
import pandas as pd s = pd.Series(['Tom', 'William Rick', 'John', 'Alber@t']) print s.str.isnumeric()
其 **输出** 如下:
0 False 1 False 2 False 3 False dtype: bool
Python Pandas - 选项和自定义
Pandas提供API来定制其行为的某些方面,主要用于显示。
该API包含五个相关的函数,它们是:
- get_option()
- set_option()
- reset_option()
- describe_option()
- option_context()
现在让我们了解这些函数是如何工作的。
get_option(param)
get_option接受单个参数并返回如下所示的值:
display.max_rows
显示默认值的数量。解释器读取此值,并以此值为显示行的上限。
import pandas as pd print pd.get_option("display.max_rows")
其 **输出** 如下:
60
display.max_columns
显示默认值的数量。解释器读取此值,并以此值为显示行的上限。
import pandas as pd print pd.get_option("display.max_columns")
其 **输出** 如下:
20
这里,60和20是默认配置参数值。
set_option(param,value)
set_option接受两个参数并将值设置为参数,如下所示:
display.max_rows
使用set_option(),我们可以更改要显示的默认行数。
import pandas as pd pd.set_option("display.max_rows",80) print pd.get_option("display.max_rows")
其 **输出** 如下:
80
display.max_columns
使用set_option(),我们可以更改要显示的默认行数。
import pandas as pd pd.set_option("display.max_columns",30) print pd.get_option("display.max_columns")
其 **输出** 如下:
30
reset_option(param)
reset_option接受一个参数并将值重置为默认值。
display.max_rows
使用reset_option(),我们可以将值改回要显示的默认行数。
import pandas as pd pd.reset_option("display.max_rows") print pd.get_option("display.max_rows")
其 **输出** 如下:
60
describe_option(param)
describe_option打印参数的描述。
display.max_rows
使用reset_option(),我们可以将值改回要显示的默认行数。
import pandas as pd pd.describe_option("display.max_rows")
其 **输出** 如下:
display.max_rows : int If max_rows is exceeded, switch to truncate view. Depending on 'large_repr', objects are either centrally truncated or printed as a summary view. 'None' value means unlimited. In case python/IPython is running in a terminal and `large_repr` equals 'truncate' this can be set to 0 and pandas will auto-detect the height of the terminal and print a truncated object which fits the screen height. The IPython notebook, IPython qtconsole, or IDLE do not run in a terminal and hence it is not possible to do correct auto-detection. [default: 60] [currently: 60]
option_context()
option_context上下文管理器用于在with语句中临时设置选项。当退出with块时,选项值会自动恢复。
display.max_rows
使用option_context(),我们可以临时设置值。
import pandas as pd with pd.option_context("display.max_rows",10): print(pd.get_option("display.max_rows")) print(pd.get_option("display.max_rows"))
其 **输出** 如下:
10 10
请看第一个和第二个print语句的区别。第一个语句打印由option_context()设置的值,该值仅在with上下文中是临时的。在with上下文之后,第二个print语句打印配置的值。
常用参数
序号 | 参数和描述 |
---|---|
1 |
display.max_rows 显示要显示的最大行数 |
2 |
2 display.max_columns 显示要显示的最大列数 |
3 |
display.expand_frame_repr 显示DataFrames以扩展页面 |
4 |
display.max_colwidth 显示最大列宽 |
5 |
display.precision 显示小数的精度 |
Python Pandas - 索引和数据选择
在本章中,我们将讨论如何切片和处理日期,以及如何一般地获取Pandas对象的子集。
Python和NumPy的索引运算符“[ ]”和属性运算符“.”为Pandas数据结构提供了快速简便的访问方式,适用于各种用例。但是,由于要访问的数据类型事先未知,因此直接使用标准运算符存在一些优化限制。对于生产代码,我们建议您利用本章中解释的优化的Pandas数据访问方法。
Pandas现在支持三种类型的多轴索引;三种类型在以下表格中提到:
序号 | 索引和描述 |
---|---|
1 |
.loc() 基于标签 |
2 |
.iloc() 基于整数 |
3 |
.ix() 基于标签和整数 |
.loc()
Pandas提供各种方法来进行纯粹的基于标签的索引。在切片时,起始边界也包括在内。整数是有效的标签,但它们指的是标签而不是位置。
.loc()有多种访问方法,例如:
- 单个标量标签
- 标签列表
- 切片对象
- 布尔数组
loc接受两个用“,”分隔的单个/列表/范围运算符。第一个表示行,第二个表示列。
示例 1
#import the pandas library and aliasing as pd import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), index = ['a','b','c','d','e','f','g','h'], columns = ['A', 'B', 'C', 'D']) #select all rows for a specific column print df.loc[:,'A']
其 **输出** 如下:
a 0.391548 b -0.070649 c -0.317212 d -2.162406 e 2.202797 f 0.613709 g 1.050559 h 1.122680 Name: A, dtype: float64
示例 2
# import the pandas library and aliasing as pd import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), index = ['a','b','c','d','e','f','g','h'], columns = ['A', 'B', 'C', 'D']) # Select all rows for multiple columns, say list[] print df.loc[:,['A','C']]
其 **输出** 如下:
A C a 0.391548 0.745623 b -0.070649 1.620406 c -0.317212 1.448365 d -2.162406 -0.873557 e 2.202797 0.528067 f 0.613709 0.286414 g 1.050559 0.216526 h 1.122680 -1.621420
示例3
# import the pandas library and aliasing as pd import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), index = ['a','b','c','d','e','f','g','h'], columns = ['A', 'B', 'C', 'D']) # Select few rows for multiple columns, say list[] print df.loc[['a','b','f','h'],['A','C']]
其 **输出** 如下:
A C a 0.391548 0.745623 b -0.070649 1.620406 f 0.613709 0.286414 h 1.122680 -1.621420
示例4
# import the pandas library and aliasing as pd import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), index = ['a','b','c','d','e','f','g','h'], columns = ['A', 'B', 'C', 'D']) # Select range of rows for all columns print df.loc['a':'h']
其 **输出** 如下:
A B C D a 0.391548 -0.224297 0.745623 0.054301 b -0.070649 -0.880130 1.620406 1.419743 c -0.317212 -1.929698 1.448365 0.616899 d -2.162406 0.614256 -0.873557 1.093958 e 2.202797 -2.315915 0.528067 0.612482 f 0.613709 -0.157674 0.286414 -0.500517 g 1.050559 -2.272099 0.216526 0.928449 h 1.122680 0.324368 -1.621420 -0.741470
示例5
# import the pandas library and aliasing as pd import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), index = ['a','b','c','d','e','f','g','h'], columns = ['A', 'B', 'C', 'D']) # for getting values with a boolean array print df.loc['a']>0
其 **输出** 如下:
A False B True C False D False Name: a, dtype: bool
.iloc()
Pandas提供各种方法来进行纯粹的基于整数的索引。像Python和NumPy一样,这些是基于0的索引。
各种访问方法如下:
- 一个整数
- 整数列表
- 一系列值
示例 1
# import the pandas library and aliasing as pd import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) # select all rows for a specific column print df.iloc[:4]
其 **输出** 如下:
A B C D 0 0.699435 0.256239 -1.270702 -0.645195 1 -0.685354 0.890791 -0.813012 0.631615 2 -0.783192 -0.531378 0.025070 0.230806 3 0.539042 -1.284314 0.826977 -0.026251
示例 2
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) # Integer slicing print df.iloc[:4] print df.iloc[1:5, 2:4]
其 **输出** 如下:
A B C D 0 0.699435 0.256239 -1.270702 -0.645195 1 -0.685354 0.890791 -0.813012 0.631615 2 -0.783192 -0.531378 0.025070 0.230806 3 0.539042 -1.284314 0.826977 -0.026251 C D 1 -0.813012 0.631615 2 0.025070 0.230806 3 0.826977 -0.026251 4 1.423332 1.130568
示例3
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) # Slicing through list of values print df.iloc[[1, 3, 5], [1, 3]] print df.iloc[1:3, :] print df.iloc[:,1:3]
其 **输出** 如下:
B D 1 0.890791 0.631615 3 -1.284314 -0.026251 5 -0.512888 -0.518930 A B C D 1 -0.685354 0.890791 -0.813012 0.631615 2 -0.783192 -0.531378 0.025070 0.230806 B C 0 0.256239 -1.270702 1 0.890791 -0.813012 2 -0.531378 0.025070 3 -1.284314 0.826977 4 -0.460729 1.423332 5 -0.512888 0.581409 6 -1.204853 0.098060 7 -0.947857 0.641358
.ix()
除了纯粹的基于标签和基于整数的索引外,Pandas还提供了一种混合方法,可以使用.ix()运算符选择和子集对象。
示例 1
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) # Integer slicing print df.ix[:4]
其 **输出** 如下:
A B C D 0 0.699435 0.256239 -1.270702 -0.645195 1 -0.685354 0.890791 -0.813012 0.631615 2 -0.783192 -0.531378 0.025070 0.230806 3 0.539042 -1.284314 0.826977 -0.026251
示例 2
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) # Index slicing print df.ix[:,'A']
其 **输出** 如下:
0 0.699435 1 -0.685354 2 -0.783192 3 0.539042 4 -1.044209 5 -1.415411 6 1.062095 7 0.994204 Name: A, dtype: float64
符号的使用
使用多轴索引从Pandas对象中获取值使用以下符号:
对象 | 索引器 | 返回类型 |
---|---|---|
Series | s.loc[indexer] | 标量值 |
DataFrame | df.loc[row_index,col_index] | Series对象 |
Panel | p.loc[item_index,major_index, minor_index] | p.loc[item_index,major_index, minor_index] |
注意 - .iloc() & .ix() 应用相同的索引选项和返回值。
现在让我们看看如何在DataFrame对象上执行每个操作。我们将使用基本的索引运算符“[ ]”
示例 1
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) print df['A']
其 **输出** 如下:
0 -0.478893 1 0.391931 2 0.336825 3 -1.055102 4 -0.165218 5 -0.328641 6 0.567721 7 -0.759399 Name: A, dtype: float64
注意 - 我们可以将值列表传递给“[ ]”以选择这些列。
示例 2
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) print df[['A','B']]
其 **输出** 如下:
A B 0 -0.478893 -0.606311 1 0.391931 -0.949025 2 0.336825 0.093717 3 -1.055102 -0.012944 4 -0.165218 1.550310 5 -0.328641 -0.226363 6 0.567721 -0.312585 7 -0.759399 -0.372696
示例3
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) print df[2:2]
其 **输出** 如下:
Columns: [A, B, C, D] Index: []
属性访问
可以使用属性运算符“.”选择列。
示例
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(8, 4), columns = ['A', 'B', 'C', 'D']) print df.A
其 **输出** 如下:
0 -0.478893 1 0.391931 2 0.336825 3 -1.055102 4 -0.165218 5 -0.328641 6 0.567721 7 -0.759399 Name: A, dtype: float64
Python Pandas - 统计函数
统计方法有助于理解和分析数据的行为。现在我们将学习一些统计函数,这些函数可以应用于Pandas对象。
百分比变化
Series、DataFrames和Panel都有函数pct_change()。此函数将每个元素与其之前的元素进行比较并计算变化百分比。
import pandas as pd import numpy as np s = pd.Series([1,2,3,4,5,4]) print s.pct_change() df = pd.DataFrame(np.random.randn(5, 2)) print df.pct_change()
其 **输出** 如下:
0 NaN 1 1.000000 2 0.500000 3 0.333333 4 0.250000 5 -0.200000 dtype: float64 0 1 0 NaN NaN 1 -15.151902 0.174730 2 -0.746374 -1.449088 3 -3.582229 -3.165836 4 15.601150 -1.860434
默认情况下,pct_change()作用于列;如果要按行应用相同的操作,则使用axis=1()参数。
协方差
协方差应用于系列数据。Series对象有一个cov方法来计算系列对象之间的协方差。NA将自动排除。
Cov Series
import pandas as pd import numpy as np s1 = pd.Series(np.random.randn(10)) s2 = pd.Series(np.random.randn(10)) print s1.cov(s2)
其 **输出** 如下:
-0.12978405324
当协方差方法应用于DataFrame时,计算所有列之间的cov。
import pandas as pd import numpy as np frame = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e']) print frame['a'].cov(frame['b']) print frame.cov()
其 **输出** 如下:
-0.58312921152741437 a b c d e a 1.780628 -0.583129 -0.185575 0.003679 -0.136558 b -0.583129 1.297011 0.136530 -0.523719 0.251064 c -0.185575 0.136530 0.915227 -0.053881 -0.058926 d 0.003679 -0.523719 -0.053881 1.521426 -0.487694 e -0.136558 0.251064 -0.058926 -0.487694 0.960761
注意 - 观察第一个语句中a和b列之间的cov,该值与DataFrame上的cov返回的值相同。
相关性
相关性显示任何两个值数组(序列)之间的线性关系。有多种方法可以计算相关性,例如pearson(默认)、spearman和kendall。
import pandas as pd import numpy as np frame = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e']) print frame['a'].corr(frame['b']) print frame.corr()
其 **输出** 如下:
-0.383712785514 a b c d e a 1.000000 -0.383713 -0.145368 0.002235 -0.104405 b -0.383713 1.000000 0.125311 -0.372821 0.224908 c -0.145368 0.125311 1.000000 -0.045661 -0.062840 d 0.002235 -0.372821 -0.045661 1.000000 -0.403380 e -0.104405 0.224908 -0.062840 -0.403380 1.000000
如果DataFrame中存在任何非数字列,则会自动将其排除。
数据排名
数据排名为元素数组中的每个元素生成排名。如果出现平局,则分配平均排名。
import pandas as pd import numpy as np s = pd.Series(np.random.np.random.randn(5), index=list('abcde')) s['d'] = s['b'] # so there's a tie print s.rank()
其 **输出** 如下:
a 1.0 b 3.5 c 2.0 d 3.5 e 5.0 dtype: float64
Rank可选地接受一个ascending参数,默认为true;当为false时,数据被反向排名,较大的值被赋予较小的排名。
Rank支持不同的平局分解方法,由method参数指定:
average - 平局组的平均排名
min - 组中的最低排名
max - 组中的最高排名
first - 按数组中出现的顺序分配排名
Python Pandas - 窗口函数
对于数值数据,Pandas提供了一些变体,例如滚动、扩展和指数移动权重,用于窗口统计。其中包括sum、mean、median、variance、covariance、correlation等。
现在我们将学习如何在DataFrame对象上应用这些方法。
.rolling() 函数
此函数可以应用于一系列数据。指定window=n参数,并在其上应用适当的统计函数。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df.rolling(window=3).mean()
其 **输出** 如下:
A B C D 2000-01-01 NaN NaN NaN NaN 2000-01-02 NaN NaN NaN NaN 2000-01-03 0.434553 -0.667940 -1.051718 -0.826452 2000-01-04 0.628267 -0.047040 -0.287467 -0.161110 2000-01-05 0.398233 0.003517 0.099126 -0.405565 2000-01-06 0.641798 0.656184 -0.322728 0.428015 2000-01-07 0.188403 0.010913 -0.708645 0.160932 2000-01-08 0.188043 -0.253039 -0.818125 -0.108485 2000-01-09 0.682819 -0.606846 -0.178411 -0.404127 2000-01-10 0.688583 0.127786 0.513832 -1.067156
注意 - 由于窗口大小为3,因此对于前两个元素存在空值,从第三个元素开始,其值为n、n-1和n-2元素的平均值。因此,我们也可以应用上面提到的各种函数。
.expanding() 函数
此函数可以应用于一系列数据。指定min_periods=n参数,并在其上应用适当的统计函数。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df.expanding(min_periods=3).mean()
其 **输出** 如下:
A B C D 2000-01-01 NaN NaN NaN NaN 2000-01-02 NaN NaN NaN NaN 2000-01-03 0.434553 -0.667940 -1.051718 -0.826452 2000-01-04 0.743328 -0.198015 -0.852462 -0.262547 2000-01-05 0.614776 -0.205649 -0.583641 -0.303254 2000-01-06 0.538175 -0.005878 -0.687223 -0.199219 2000-01-07 0.505503 -0.108475 -0.790826 -0.081056 2000-01-08 0.454751 -0.223420 -0.671572 -0.230215 2000-01-09 0.586390 -0.206201 -0.517619 -0.267521 2000-01-10 0.560427 -0.037597 -0.399429 -0.376886
.ewm() 函数
ewm应用于一系列数据。指定com、span、halflife参数中的任何一个,并在其上应用适当的统计函数。它以指数方式分配权重。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df.ewm(com=0.5).mean()
其 **输出** 如下:
A B C D 2000-01-01 1.088512 -0.650942 -2.547450 -0.566858 2000-01-02 0.865131 -0.453626 -1.137961 0.058747 2000-01-03 -0.132245 -0.807671 -0.308308 -1.491002 2000-01-04 1.084036 0.555444 -0.272119 0.480111 2000-01-05 0.425682 0.025511 0.239162 -0.153290 2000-01-06 0.245094 0.671373 -0.725025 0.163310 2000-01-07 0.288030 -0.259337 -1.183515 0.473191 2000-01-08 0.162317 -0.771884 -0.285564 -0.692001 2000-01-09 1.147156 -0.302900 0.380851 -0.607976 2000-01-10 0.600216 0.885614 0.569808 -1.110113
窗口函数主要用于通过平滑曲线来图形化地查找数据中的趋势。如果日常数据变化很大并且有很多数据点可用,那么抽样和绘图是一种方法,应用窗口计算并在结果上绘制图形是另一种方法。通过这些方法,我们可以平滑曲线或趋势。
Python Pandas - 聚合
创建滚动、扩展和ewm对象后,可以使用多种方法对数据进行聚合。
在DataFrame上应用聚合
让我们创建一个DataFrame并在其上应用聚合。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df r = df.rolling(window=3,min_periods=1) print r
其 **输出** 如下:
A B C D 2000-01-01 1.088512 -0.650942 -2.547450 -0.566858 2000-01-02 0.790670 -0.387854 -0.668132 0.267283 2000-01-03 -0.575523 -0.965025 0.060427 -2.179780 2000-01-04 1.669653 1.211759 -0.254695 1.429166 2000-01-05 0.100568 -0.236184 0.491646 -0.466081 2000-01-06 0.155172 0.992975 -1.205134 0.320958 2000-01-07 0.309468 -0.724053 -1.412446 0.627919 2000-01-08 0.099489 -1.028040 0.163206 -1.274331 2000-01-09 1.639500 -0.068443 0.714008 -0.565969 2000-01-10 0.326761 1.479841 0.664282 -1.361169 Rolling [window=3,min_periods=1,center=False,axis=0]
我们可以通过将函数传递给整个DataFrame来进行聚合,或者通过标准的get item方法选择一列。
在整个DataFrame上应用聚合
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df r = df.rolling(window=3,min_periods=1) print r.aggregate(np.sum)
其 **输出** 如下:
A B C D 2000-01-01 1.088512 -0.650942 -2.547450 -0.566858 2000-01-02 1.879182 -1.038796 -3.215581 -0.299575 2000-01-03 1.303660 -2.003821 -3.155154 -2.479355 2000-01-04 1.884801 -0.141119 -0.862400 -0.483331 2000-01-05 1.194699 0.010551 0.297378 -1.216695 2000-01-06 1.925393 1.968551 -0.968183 1.284044 2000-01-07 0.565208 0.032738 -2.125934 0.482797 2000-01-08 0.564129 -0.759118 -2.454374 -0.325454 2000-01-09 2.048458 -1.820537 -0.535232 -1.212381 2000-01-10 2.065750 0.383357 1.541496 -3.201469 A B C D 2000-01-01 1.088512 -0.650942 -2.547450 -0.566858 2000-01-02 1.879182 -1.038796 -3.215581 -0.299575 2000-01-03 1.303660 -2.003821 -3.155154 -2.479355 2000-01-04 1.884801 -0.141119 -0.862400 -0.483331 2000-01-05 1.194699 0.010551 0.297378 -1.216695 2000-01-06 1.925393 1.968551 -0.968183 1.284044 2000-01-07 0.565208 0.032738 -2.125934 0.482797 2000-01-08 0.564129 -0.759118 -2.454374 -0.325454 2000-01-09 2.048458 -1.820537 -0.535232 -1.212381 2000-01-10 2.065750 0.383357 1.541496 -3.201469
在DataFrame的单个列上应用聚合
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df r = df.rolling(window=3,min_periods=1) print r['A'].aggregate(np.sum)
其 **输出** 如下:
A B C D 2000-01-01 1.088512 -0.650942 -2.547450 -0.566858 2000-01-02 1.879182 -1.038796 -3.215581 -0.299575 2000-01-03 1.303660 -2.003821 -3.155154 -2.479355 2000-01-04 1.884801 -0.141119 -0.862400 -0.483331 2000-01-05 1.194699 0.010551 0.297378 -1.216695 2000-01-06 1.925393 1.968551 -0.968183 1.284044 2000-01-07 0.565208 0.032738 -2.125934 0.482797 2000-01-08 0.564129 -0.759118 -2.454374 -0.325454 2000-01-09 2.048458 -1.820537 -0.535232 -1.212381 2000-01-10 2.065750 0.383357 1.541496 -3.201469 2000-01-01 1.088512 2000-01-02 1.879182 2000-01-03 1.303660 2000-01-04 1.884801 2000-01-05 1.194699 2000-01-06 1.925393 2000-01-07 0.565208 2000-01-08 0.564129 2000-01-09 2.048458 2000-01-10 2.065750 Freq: D, Name: A, dtype: float64
在DataFrame的多个列上应用聚合
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df r = df.rolling(window=3,min_periods=1) print r[['A','B']].aggregate(np.sum)
其 **输出** 如下:
A B C D 2000-01-01 1.088512 -0.650942 -2.547450 -0.566858 2000-01-02 1.879182 -1.038796 -3.215581 -0.299575 2000-01-03 1.303660 -2.003821 -3.155154 -2.479355 2000-01-04 1.884801 -0.141119 -0.862400 -0.483331 2000-01-05 1.194699 0.010551 0.297378 -1.216695 2000-01-06 1.925393 1.968551 -0.968183 1.284044 2000-01-07 0.565208 0.032738 -2.125934 0.482797 2000-01-08 0.564129 -0.759118 -2.454374 -0.325454 2000-01-09 2.048458 -1.820537 -0.535232 -1.212381 2000-01-10 2.065750 0.383357 1.541496 -3.201469 A B 2000-01-01 1.088512 -0.650942 2000-01-02 1.879182 -1.038796 2000-01-03 1.303660 -2.003821 2000-01-04 1.884801 -0.141119 2000-01-05 1.194699 0.010551 2000-01-06 1.925393 1.968551 2000-01-07 0.565208 0.032738 2000-01-08 0.564129 -0.759118 2000-01-09 2.048458 -1.820537 2000-01-10 2.065750 0.383357
在DataFrame的单个列上应用多个函数
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df r = df.rolling(window=3,min_periods=1) print r['A'].aggregate([np.sum,np.mean])
其 **输出** 如下:
A B C D 2000-01-01 1.088512 -0.650942 -2.547450 -0.566858 2000-01-02 1.879182 -1.038796 -3.215581 -0.299575 2000-01-03 1.303660 -2.003821 -3.155154 -2.479355 2000-01-04 1.884801 -0.141119 -0.862400 -0.483331 2000-01-05 1.194699 0.010551 0.297378 -1.216695 2000-01-06 1.925393 1.968551 -0.968183 1.284044 2000-01-07 0.565208 0.032738 -2.125934 0.482797 2000-01-08 0.564129 -0.759118 -2.454374 -0.325454 2000-01-09 2.048458 -1.820537 -0.535232 -1.212381 2000-01-10 2.065750 0.383357 1.541496 -3.201469 sum mean 2000-01-01 1.088512 1.088512 2000-01-02 1.879182 0.939591 2000-01-03 1.303660 0.434553 2000-01-04 1.884801 0.628267 2000-01-05 1.194699 0.398233 2000-01-06 1.925393 0.641798 2000-01-07 0.565208 0.188403 2000-01-08 0.564129 0.188043 2000-01-09 2.048458 0.682819 2000-01-10 2.065750 0.688583
在DataFrame的多个列上应用多个函数
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), index = pd.date_range('1/1/2000', periods=10), columns = ['A', 'B', 'C', 'D']) print df r = df.rolling(window=3,min_periods=1) print r[['A','B']].aggregate([np.sum,np.mean])
其 **输出** 如下:
A B C D 2000-01-01 1.088512 -0.650942 -2.547450 -0.566858 2000-01-02 1.879182 -1.038796 -3.215581 -0.299575 2000-01-03 1.303660 -2.003821 -3.155154 -2.479355 2000-01-04 1.884801 -0.141119 -0.862400 -0.483331 2000-01-05 1.194699 0.010551 0.297378 -1.216695 2000-01-06 1.925393 1.968551 -0.968183 1.284044 2000-01-07 0.565208 0.032738 -2.125934 0.482797 2000-01-08 0.564129 -0.759118 -2.454374 -0.325454 2000-01-09 2.048458 -1.820537 -0.535232 -1.212381 2000-01-10 2.065750 0.383357 1.541496 -3.201469 A B sum mean sum mean 2000-01-01 1.088512 1.088512 -0.650942 -0.650942 2000-01-02 1.879182 0.939591 -1.038796 -0.519398 2000-01-03 1.303660 0.434553 -2.003821 -0.667940 2000-01-04 1.884801 0.628267 -0.141119 -0.047040 2000-01-05 1.194699 0.398233 0.010551 0.003517 2000-01-06 1.925393 0.641798 1.968551 0.656184 2000-01-07 0.565208 0.188403 0.032738 0.010913 2000-01-08 0.564129 0.188043 -0.759118 -0.253039 2000-01-09 2.048458 0.682819 -1.820537 -0.606846 2000-01-10 2.065750 0.688583 0.383357 0.127786
将不同的函数应用于DataFrame的不同列
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(3, 4), index = pd.date_range('1/1/2000', periods=3), columns = ['A', 'B', 'C', 'D']) print df r = df.rolling(window=3,min_periods=1) print r.aggregate({'A' : np.sum,'B' : np.mean})
其 **输出** 如下:
A B C D 2000-01-01 -1.575749 -1.018105 0.317797 0.545081 2000-01-02 -0.164917 -1.361068 0.258240 1.113091 2000-01-03 1.258111 1.037941 -0.047487 0.867371 A B 2000-01-01 -1.575749 -1.018105 2000-01-02 -1.740666 -1.189587 2000-01-03 -0.482555 -0.447078
Python Pandas - 缺失数据
缺失数据在现实场景中始终是一个问题。机器学习和数据挖掘等领域由于数据质量差(由缺失值引起),其模型预测的准确性面临严重问题。在这些领域,缺失值处理是提高模型准确性和有效性的一个主要关注点。
数据何时以及为何缺失?
让我们考虑一个产品的在线调查。很多时候,人们不会分享与他们相关的所有信息。一些人分享他们的体验,但没有分享他们使用产品的时间长短;一些人分享他们使用产品的时间长短和他们的体验,但没有分享他们的联系方式。因此,以某种方式,数据的一部分总是缺失的,这在实时数据中非常常见。
现在让我们看看如何使用Pandas处理缺失值(例如NA或NaN)。
# import the pandas library import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print df
其 **输出** 如下:
one two three a 0.077988 0.476149 0.965836 b NaN NaN NaN c -0.390208 -0.551605 -2.301950 d NaN NaN NaN e -2.000303 -0.788201 1.510072 f -0.930230 -0.670473 1.146615 g NaN NaN NaN h 0.085100 0.532791 0.887415
使用重新索引,我们创建了一个包含缺失值的DataFrame。在输出中,NaN 表示非数字。
检查缺失值
为了更容易地检测缺失值(并跨越不同的数组数据类型),Pandas提供了isnull()和notnull()函数,它们也是Series和DataFrame对象的的方法−
示例 1
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print df['one'].isnull()
其 **输出** 如下:
a False b True c False d True e False f False g True h False Name: one, dtype: bool
示例 2
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print df['one'].notnull()
其 **输出** 如下:
a True b False c True d False e True f True g False h True Name: one, dtype: bool
缺失数据的计算
- 在对数据求和时,NA将被视为零。
- 如果数据全是NA,则结果将为NA。
示例 1
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print df['one'].sum()
其 **输出** 如下:
2.02357685917
示例 2
import pandas as pd import numpy as np df = pd.DataFrame(index=[0,1,2,3,4,5],columns=['one','two']) print df['one'].sum()
其 **输出** 如下:
nan
清理/填充缺失数据
Pandas提供了多种清理缺失值的方法。fillna函数可以通过几种方式用非空数据“填充”NA值,我们在以下章节中进行了说明。
用标量值替换NaN
以下程序显示了如何用“0”替换“NaN”。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(3, 3), index=['a', 'c', 'e'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c']) print df print ("NaN replaced with '0':") print df.fillna(0)
其 **输出** 如下:
one two three a -0.576991 -0.741695 0.553172 b NaN NaN NaN c 0.744328 -1.735166 1.749580 NaN replaced with '0': one two three a -0.576991 -0.741695 0.553172 b 0.000000 0.000000 0.000000 c 0.744328 -1.735166 1.749580
这里,我们用零填充;我们也可以用任何其他值填充。
向前和向后填充NA
使用重新索引章节中讨论的填充概念,我们将填充缺失值。
序号 | 方法和操作 |
---|---|
1 |
pad/fill 向前填充方法 |
2 |
bfill/backfill 向后填充方法 |
示例 1
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print df.fillna(method='pad')
其 **输出** 如下:
one two three a 0.077988 0.476149 0.965836 b 0.077988 0.476149 0.965836 c -0.390208 -0.551605 -2.301950 d -0.390208 -0.551605 -2.301950 e -2.000303 -0.788201 1.510072 f -0.930230 -0.670473 1.146615 g -0.930230 -0.670473 1.146615 h 0.085100 0.532791 0.887415
示例 2
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print df.fillna(method='backfill')
其 **输出** 如下:
one two three a 0.077988 0.476149 0.965836 b -0.390208 -0.551605 -2.301950 c -0.390208 -0.551605 -2.301950 d -2.000303 -0.788201 1.510072 e -2.000303 -0.788201 1.510072 f -0.930230 -0.670473 1.146615 g 0.085100 0.532791 0.887415 h 0.085100 0.532791 0.887415
删除缺失值
如果只想排除缺失值,则使用dropna函数以及axis参数。默认情况下,axis=0,即沿行,这意味着如果一行中的任何值都是NA,则整行都将被排除。
示例 1
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print df.dropna()
其 **输出** 如下:
one two three a 0.077988 0.476149 0.965836 c -0.390208 -0.551605 -2.301950 e -2.000303 -0.788201 1.510072 f -0.930230 -0.670473 1.146615 h 0.085100 0.532791 0.887415
示例 2
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three']) df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) print df.dropna(axis=1)
其 **输出** 如下:
Empty DataFrame Columns: [ ] Index: [a, b, c, d, e, f, g, h]
替换缺失值(或)通用值
很多时候,我们必须用某个特定值替换通用值。我们可以通过应用replace方法来实现这一点。
用标量值替换NA等同于fillna()函数的行为。
示例 1
import pandas as pd import numpy as np df = pd.DataFrame({'one':[10,20,30,40,50,2000], 'two':[1000,0,30,40,50,60]}) print df.replace({1000:10,2000:60})
其 **输出** 如下:
one two 0 10 10 1 20 0 2 30 30 3 40 40 4 50 50 5 60 60
示例 2
import pandas as pd import numpy as np df = pd.DataFrame({'one':[10,20,30,40,50,2000], 'two':[1000,0,30,40,50,60]}) print df.replace({1000:10,2000:60})
其 **输出** 如下:
one two 0 10 10 1 20 0 2 30 30 3 40 40 4 50 50 5 60 60
Python Pandas - GroupBy
任何groupby操作都涉及对原始对象执行以下操作之一。它们是−
拆分对象
应用函数
组合结果
在许多情况下,我们将数据拆分成多个集合,并在每个子集上应用一些功能。在应用功能中,我们可以执行以下操作−
聚合−计算汇总统计数据
转换−执行一些特定于组的操作
过滤−根据某些条件丢弃数据
现在让我们创建一个DataFrame对象,并在其上执行所有操作−
#import the pandas library import pandas as pd ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) print df
其 **输出** 如下:
Points Rank Team Year 0 876 1 Riders 2014 1 789 2 Riders 2015 2 863 2 Devils 2014 3 673 3 Devils 2015 4 741 3 Kings 2014 5 812 4 kings 2015 6 756 1 Kings 2016 7 788 1 Kings 2017 8 694 2 Riders 2016 9 701 4 Royals 2014 10 804 1 Royals 2015 11 690 2 Riders 2017
将数据分成组
Pandas对象可以拆分成任何其对象。有多种方法可以拆分对象,例如−
- obj.groupby('key')
- obj.groupby(['key1','key2'])
- obj.groupby(key,axis=1)
现在让我们看看如何将分组对象应用于DataFrame对象。
示例
# import the pandas library import pandas as pd ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) print df.groupby('Team')
其 **输出** 如下:
<pandas.core.groupby.DataFrameGroupBy object at 0x7fa46a977e50>
查看组
# import the pandas library import pandas as pd ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) print df.groupby('Team').groups
其 **输出** 如下:
{'Kings': Int64Index([4, 6, 7], dtype='int64'), 'Devils': Int64Index([2, 3], dtype='int64'), 'Riders': Int64Index([0, 1, 8, 11], dtype='int64'), 'Royals': Int64Index([9, 10], dtype='int64'), 'kings' : Int64Index([5], dtype='int64')}
示例
分组包含多个列−
# import the pandas library import pandas as pd ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) print df.groupby(['Team','Year']).groups
其 **输出** 如下:
{('Kings', 2014): Int64Index([4], dtype='int64'), ('Royals', 2014): Int64Index([9], dtype='int64'), ('Riders', 2014): Int64Index([0], dtype='int64'), ('Riders', 2015): Int64Index([1], dtype='int64'), ('Kings', 2016): Int64Index([6], dtype='int64'), ('Riders', 2016): Int64Index([8], dtype='int64'), ('Riders', 2017): Int64Index([11], dtype='int64'), ('Devils', 2014): Int64Index([2], dtype='int64'), ('Devils', 2015): Int64Index([3], dtype='int64'), ('kings', 2015): Int64Index([5], dtype='int64'), ('Royals', 2015): Int64Index([10], dtype='int64'), ('Kings', 2017): Int64Index([7], dtype='int64')}
迭代组
有了groupby对象,我们可以像itertools.obj一样迭代该对象。
# import the pandas library import pandas as pd ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) grouped = df.groupby('Year') for name,group in grouped: print name print group
其 **输出** 如下:
2014 Points Rank Team Year 0 876 1 Riders 2014 2 863 2 Devils 2014 4 741 3 Kings 2014 9 701 4 Royals 2014 2015 Points Rank Team Year 1 789 2 Riders 2015 3 673 3 Devils 2015 5 812 4 kings 2015 10 804 1 Royals 2015 2016 Points Rank Team Year 6 756 1 Kings 2016 8 694 2 Riders 2016 2017 Points Rank Team Year 7 788 1 Kings 2017 11 690 2 Riders 2017
默认情况下,groupby对象的标签名称与组名称相同。
选择一个组
使用get_group()方法,我们可以选择单个组。
# import the pandas library import pandas as pd ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) grouped = df.groupby('Year') print grouped.get_group(2014)
其 **输出** 如下:
Points Rank Team Year 0 876 1 Riders 2014 2 863 2 Devils 2014 4 741 3 Kings 2014 9 701 4 Royals 2014
聚合
聚合函数为每个组返回单个聚合值。创建group by对象后,可以对分组数据执行多个聚合操作。
一个明显的方法是通过aggregate或等效的agg方法进行聚合−
# import the pandas library import pandas as pd import numpy as np ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) grouped = df.groupby('Year') print grouped['Points'].agg(np.mean)
其 **输出** 如下:
Year 2014 795.25 2015 769.50 2016 725.00 2017 739.00 Name: Points, dtype: float64
另一种查看每个组大小的方法是应用size()函数−
import pandas as pd import numpy as np ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) Attribute Access in Python Pandas grouped = df.groupby('Team') print grouped.agg(np.size)
其 **输出** 如下:
Points Rank Year Team Devils 2 2 2 Kings 3 3 3 Riders 4 4 4 Royals 2 2 2 kings 1 1 1
一次应用多个聚合函数
对于分组后的Series,您还可以传递一个函数列表或函数字典来进行聚合,并生成DataFrame作为输出−
# import the pandas library import pandas as pd import numpy as np ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) grouped = df.groupby('Team') print grouped['Points'].agg([np.sum, np.mean, np.std])
其 **输出** 如下:
Team sum mean std Devils 1536 768.000000 134.350288 Kings 2285 761.666667 24.006943 Riders 3049 762.250000 88.567771 Royals 1505 752.500000 72.831998 kings 812 812.000000 NaN
转换
对组或列的转换返回一个与被分组对象大小相同的对象。因此,转换应该返回与组块大小相同的结果。
# import the pandas library import pandas as pd import numpy as np ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) grouped = df.groupby('Team') score = lambda x: (x - x.mean()) / x.std()*10 print grouped.transform(score)
其 **输出** 如下:
Points Rank Year 0 12.843272 -15.000000 -11.618950 1 3.020286 5.000000 -3.872983 2 7.071068 -7.071068 -7.071068 3 -7.071068 7.071068 7.071068 4 -8.608621 11.547005 -10.910895 5 NaN NaN NaN 6 -2.360428 -5.773503 2.182179 7 10.969049 -5.773503 8.728716 8 -7.705963 5.000000 3.872983 9 -7.071068 7.071068 -7.071068 10 7.071068 -7.071068 7.071068 11 -8.157595 5.000000 11.618950
过滤
过滤根据定义的条件过滤数据并返回数据的子集。filter()函数用于过滤数据。
import pandas as pd import numpy as np ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[876,789,863,673,741,812,756,788,694,701,804,690]} df = pd.DataFrame(ipl_data) print df.groupby('Team').filter(lambda x: len(x) >= 3)
其 **输出** 如下:
Points Rank Team Year 0 876 1 Riders 2014 1 789 2 Riders 2015 4 741 3 Kings 2014 6 756 1 Kings 2016 7 788 1 Kings 2017 8 694 2 Riders 2016 11 690 2 Riders 2017
在上面的过滤条件中,我们要求返回在IPL中参赛三次或三次以上的队伍。
Python Pandas - 合并/连接
Pandas具有功能齐全、高性能的内存内连接操作,其用法与SQL等关系数据库非常相似。
Pandas提供了一个单一函数merge,作为DataFrame对象之间所有标准数据库连接操作的入口点−
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True)
这里,我们使用了以下参数−
left − 一个DataFrame对象。
right − 另一个DataFrame对象。
on − 要连接的列(名称)。必须在左和右DataFrame对象中找到。
left_on − 从左DataFrame中用作键的列。可以是列名,也可以是长度等于DataFrame长度的数组。
right_on − 从右DataFrame中用作键的列。可以是列名,也可以是长度等于DataFrame长度的数组。
left_index − 如果为True,则使用左DataFrame的索引(行标签)作为其连接键。对于具有多索引(分层)的DataFrame,级别数必须与右DataFrame的连接键数匹配。
right_index − 与右DataFrame的left_index用法相同。
how − 'left'、'right'、'outer'、'inner'之一。默认为inner。每种方法都已在下面描述。
sort − 按字典顺序对结果DataFrame进行排序。默认为True,设置为False在许多情况下会大大提高性能。
现在让我们创建两个不同的DataFrame,并在其上执行合并操作。
# import the pandas library import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5']}) right = pd.DataFrame( {'id':[1,2,3,4,5], 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5']}) print left print right
其 **输出** 如下:
Name id subject_id 0 Alex 1 sub1 1 Amy 2 sub2 2 Allen 3 sub4 3 Alice 4 sub6 4 Ayoung 5 sub5 Name id subject_id 0 Billy 1 sub2 1 Brian 2 sub4 2 Bran 3 sub3 3 Bryce 4 sub6 4 Betty 5 sub5
根据键合并两个DataFrame
import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5']}) right = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5']}) print pd.merge(left,right,on='id')
其 **输出** 如下:
Name_x id subject_id_x Name_y subject_id_y 0 Alex 1 sub1 Billy sub2 1 Amy 2 sub2 Brian sub4 2 Allen 3 sub4 Bran sub3 3 Alice 4 sub6 Bryce sub6 4 Ayoung 5 sub5 Betty sub5
根据多个键合并两个DataFrame
import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5']}) right = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5']}) print pd.merge(left,right,on=['id','subject_id'])
其 **输出** 如下:
Name_x id subject_id Name_y 0 Alice 4 sub6 Bryce 1 Ayoung 5 sub5 Betty
使用'how'参数合并
how参数用于合并,指定如何确定结果表中要包含哪些键。如果键组合不出现在左表或右表中,则连接表中的值将为NA。
以下是how选项及其SQL等效名称的摘要−
合并方法 | SQL等效项 | 描述 |
---|---|---|
left | LEFT OUTER JOIN | 使用左对象的键 |
right | RIGHT OUTER JOIN | 使用右对象的键 |
outer | FULL OUTER JOIN | 使用键的并集 |
inner | INNER JOIN | 使用键的交集 |
左连接
import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5']}) right = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5']}) print pd.merge(left, right, on='subject_id', how='left')
其 **输出** 如下:
Name_x id_x subject_id Name_y id_y 0 Alex 1 sub1 NaN NaN 1 Amy 2 sub2 Billy 1.0 2 Allen 3 sub4 Brian 2.0 3 Alice 4 sub6 Bryce 4.0 4 Ayoung 5 sub5 Betty 5.0
右连接
import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5']}) right = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5']}) print pd.merge(left, right, on='subject_id', how='right')
其 **输出** 如下:
Name_x id_x subject_id Name_y id_y 0 Amy 2.0 sub2 Billy 1 1 Allen 3.0 sub4 Brian 2 2 Alice 4.0 sub6 Bryce 4 3 Ayoung 5.0 sub5 Betty 5 4 NaN NaN sub3 Bran 3
外连接
import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5']}) right = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5']}) print pd.merge(left, right, how='outer', on='subject_id')
其 **输出** 如下:
Name_x id_x subject_id Name_y id_y 0 Alex 1.0 sub1 NaN NaN 1 Amy 2.0 sub2 Billy 1.0 2 Allen 3.0 sub4 Brian 2.0 3 Alice 4.0 sub6 Bryce 4.0 4 Ayoung 5.0 sub5 Betty 5.0 5 NaN NaN sub3 Bran 3.0
内连接
连接将在索引上执行。连接操作尊重在其上调用的对象。因此,a.join(b)不等于b.join(a)。
import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5']}) right = pd.DataFrame({ 'id':[1,2,3,4,5], 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5']}) print pd.merge(left, right, on='subject_id', how='inner')
其 **输出** 如下:
Name_x id_x subject_id Name_y id_y 0 Amy 2 sub2 Billy 1 1 Allen 3 sub4 Brian 2 2 Alice 4 sub6 Bryce 4 3 Ayoung 5 sub5 Betty 5
Python Pandas - 级联
Pandas提供了各种工具,可以轻松地将Series、DataFrame和Panel对象组合在一起。
pd.concat(objs,axis=0,join='outer',join_axes=None, ignore_index=False)
objs − 这是Series、DataFrame或Panel对象的序列或映射。
axis − {0, 1, ...},默认为0。这是要沿其连接的轴。
join − {‘inner’, ‘outer’},默认为‘outer’。如何处理其他轴上的索引。外部用于联合,内部用于交集。
ignore_index − 布尔值,默认为False。如果为True,则不使用连接轴上的索引值。结果轴将标记为0、...、n - 1。
join_axes − 这是Index对象的列表。要使用的特定索引用于其他(n-1)轴,而不是执行内部/外部集合逻辑。
连接对象
concat函数完成了沿轴执行连接操作的所有繁重工作。让我们创建不同的对象并进行连接。
import pandas as pd one = pd.DataFrame({ 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5'], 'Marks_scored':[98,90,87,69,78]}, index=[1,2,3,4,5]) two = pd.DataFrame({ 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5'], 'Marks_scored':[89,80,79,97,88]}, index=[1,2,3,4,5]) print pd.concat([one,two])
其 **输出** 如下:
Marks_scored Name subject_id 1 98 Alex sub1 2 90 Amy sub2 3 87 Allen sub4 4 69 Alice sub6 5 78 Ayoung sub5 1 89 Billy sub2 2 80 Brian sub4 3 79 Bran sub3 4 97 Bryce sub6 5 88 Betty sub5
假设我们想将特定的键与分割的DataFrame的每个部分关联。我们可以使用keys参数来做到这一点−
import pandas as pd one = pd.DataFrame({ 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5'], 'Marks_scored':[98,90,87,69,78]}, index=[1,2,3,4,5]) two = pd.DataFrame({ 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5'], 'Marks_scored':[89,80,79,97,88]}, index=[1,2,3,4,5]) print pd.concat([one,two],keys=['x','y'])
其 **输出** 如下:
x 1 98 Alex sub1 2 90 Amy sub2 3 87 Allen sub4 4 69 Alice sub6 5 78 Ayoung sub5 y 1 89 Billy sub2 2 80 Brian sub4 3 79 Bran sub3 4 97 Bryce sub6 5 88 Betty sub5
结果的索引是重复的;每个索引都重复。
如果结果对象必须遵循其自身的索引,则将ignore_index设置为True。
import pandas as pd one = pd.DataFrame({ 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5'], 'Marks_scored':[98,90,87,69,78]}, index=[1,2,3,4,5]) two = pd.DataFrame({ 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5'], 'Marks_scored':[89,80,79,97,88]}, index=[1,2,3,4,5]) print pd.concat([one,two],keys=['x','y'],ignore_index=True)
其 **输出** 如下:
Marks_scored Name subject_id 0 98 Alex sub1 1 90 Amy sub2 2 87 Allen sub4 3 69 Alice sub6 4 78 Ayoung sub5 5 89 Billy sub2 6 80 Brian sub4 7 79 Bran sub3 8 97 Bryce sub6 9 88 Betty sub5
观察,索引完全改变了,键也被覆盖了。
如果需要沿axis=1添加两个对象,则将追加新列。
import pandas as pd one = pd.DataFrame({ 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5'], 'Marks_scored':[98,90,87,69,78]}, index=[1,2,3,4,5]) two = pd.DataFrame({ 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5'], 'Marks_scored':[89,80,79,97,88]}, index=[1,2,3,4,5]) print pd.concat([one,two],axis=1)
其 **输出** 如下:
Marks_scored Name subject_id Marks_scored Name subject_id 1 98 Alex sub1 89 Billy sub2 2 90 Amy sub2 80 Brian sub4 3 87 Allen sub4 79 Bran sub3 4 69 Alice sub6 97 Bryce sub6 5 78 Ayoung sub5 88 Betty sub5
使用append连接
concat的一个有用的快捷方式是Series和DataFrame上的append实例方法。这些方法实际上早于concat。它们沿axis=0连接,即索引−
import pandas as pd one = pd.DataFrame({ 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5'], 'Marks_scored':[98,90,87,69,78]}, index=[1,2,3,4,5]) two = pd.DataFrame({ 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5'], 'Marks_scored':[89,80,79,97,88]}, index=[1,2,3,4,5]) print one.append(two)
其 **输出** 如下:
Marks_scored Name subject_id 1 98 Alex sub1 2 90 Amy sub2 3 87 Allen sub4 4 69 Alice sub6 5 78 Ayoung sub5 1 89 Billy sub2 2 80 Brian sub4 3 79 Bran sub3 4 97 Bryce sub6 5 88 Betty sub5
append函数也可以接受多个对象−
import pandas as pd one = pd.DataFrame({ 'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'subject_id':['sub1','sub2','sub4','sub6','sub5'], 'Marks_scored':[98,90,87,69,78]}, index=[1,2,3,4,5]) two = pd.DataFrame({ 'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'], 'subject_id':['sub2','sub4','sub3','sub6','sub5'], 'Marks_scored':[89,80,79,97,88]}, index=[1,2,3,4,5]) print one.append([two,one,two])
其 **输出** 如下:
Marks_scored Name subject_id 1 98 Alex sub1 2 90 Amy sub2 3 87 Allen sub4 4 69 Alice sub6 5 78 Ayoung sub5 1 89 Billy sub2 2 80 Brian sub4 3 79 Bran sub3 4 97 Bryce sub6 5 88 Betty sub5 1 98 Alex sub1 2 90 Amy sub2 3 87 Allen sub4 4 69 Alice sub6 5 78 Ayoung sub5 1 89 Billy sub2 2 80 Brian sub4 3 79 Bran sub3 4 97 Bryce sub6 5 88 Betty sub5
时间序列
Pandas提供了一个强大的工具来处理时间序列数据,尤其是在金融领域。处理时间序列数据时,我们经常遇到以下情况−
- 生成时间序列
- 将时间序列转换为不同的频率
Pandas提供了一套相对紧凑且独立的工具来执行上述任务。
获取当前时间
datetime.now()提供当前日期和时间。
import pandas as pd print pd.datetime.now()
其 **输出** 如下:
2017-05-11 06:10:13.393147
创建时间戳
带时间戳的数据是最基本的时间序列数据类型,它将值与时间点相关联。对于pandas对象,这意味着使用时间点。让我们举个例子−
import pandas as pd print pd.Timestamp('2017-03-01')
其 **输出** 如下:
2017-03-01 00:00:00
也可以转换整数或浮点纪元时间。这些的默认单位是纳秒(因为这就是时间戳的存储方式)。但是,纪元通常以另一个可以指定的单位存储。让我们再举一个例子
import pandas as pd print pd.Timestamp(1587687255,unit='s')
其 **输出** 如下:
2020-04-24 00:14:15
创建时间范围
import pandas as pd print pd.date_range("11:00", "13:30", freq="30min").time
其 **输出** 如下:
[datetime.time(11, 0) datetime.time(11, 30) datetime.time(12, 0) datetime.time(12, 30) datetime.time(13, 0) datetime.time(13, 30)]
更改时间频率
import pandas as pd print pd.date_range("11:00", "13:30", freq="H").time
其 **输出** 如下:
[datetime.time(11, 0) datetime.time(12, 0) datetime.time(13, 0)]
转换为时间戳
要转换日期型对象的Series或类似列表的对象(例如字符串、纪元或混合),可以使用to_datetime函数。传递时,这将返回一个Series(具有相同的索引),而类似列表的对象将转换为DatetimeIndex。看看下面的例子−
import pandas as pd print pd.to_datetime(pd.Series(['Jul 31, 2009','2010-01-10', None]))
其 **输出** 如下:
0 2009-07-31 1 2010-01-10 2 NaT dtype: datetime64[ns]
NaT表示非时间(相当于NaN)
让我们再举一个例子。
import pandas as pd print pd.to_datetime(['2005/11/23', '2010.12.31', None])
其 **输出** 如下:
DatetimeIndex(['2005-11-23', '2010-12-31', 'NaT'], dtype='datetime64[ns]', freq=None)
Python Pandas - 日期功能
扩展时间序列,日期功能在金融数据分析中起着重要作用。处理日期数据时,我们经常会遇到以下情况−
- 生成日期序列
- 将日期序列转换为不同的频率
创建日期范围
通过指定周期和频率,使用date.range()函数,我们可以创建日期序列。默认情况下,范围的频率是天。
import pandas as pd print pd.date_range('1/1/2011', periods=5)
其 **输出** 如下:
DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04', '2011-01-05'], dtype='datetime64[ns]', freq='D')
更改日期频率
import pandas as pd print pd.date_range('1/1/2011', periods=5,freq='M')
其 **输出** 如下:
DatetimeIndex(['2011-01-31', '2011-02-28', '2011-03-31', '2011-04-30', '2011-05-31'], dtype='datetime64[ns]', freq='M')
bdate_range
bdate_range()代表业务日期范围。与date_range()不同,它不包括周六和周日。
import pandas as pd print pd.date_range('1/1/2011', periods=5)
其 **输出** 如下:
DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04', '2011-01-05'], dtype='datetime64[ns]', freq='D')
观察,3月3日之后,日期跳到3月6日,排除了4日和5日。只需查看一下您的日历即可确认日期。
诸如 **date_range** 和 **bdate_range** 之类的便捷函数使用了多种频率别名。date_range 的默认频率为日历日,而 bdate_range 的默认频率为工作日。
import pandas as pd start = pd.datetime(2011, 1, 1) end = pd.datetime(2011, 1, 5) print pd.date_range(start, end)
其 **输出** 如下:
DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04', '2011-01-05'], dtype='datetime64[ns]', freq='D')
偏移别名
许多字符串别名被赋予有用的常用时间序列频率。我们将这些别名称为偏移别名。
别名 | 描述 | 别名 | 描述 |
---|---|---|---|
B | 工作日频率 | BQS | 工作季度开始频率 |
D | 日历日频率 | A | 年度(年)末频率 |
W | 每周频率 | BA | 工作年度末频率 |
M | 月末频率 | BAS | 工作年度开始频率 |
SM | 半月末频率 | BH | 工作小时频率 |
BM | 工作月末频率 | H | 每小时频率 |
MS | 月开始频率 | T, min | 分钟频率 |
SMS | 半月开始频率 | S | 秒频率 |
BMS | 工作月开始频率 | L, ms | 毫秒 |
Q | 季度末频率 | U, us | 微秒 |
BQ | 工作季度末频率 | N | 纳秒 |
QS | 季度开始频率 |
Python Pandas - Timedelta
Timedeltas 是时间的差值,以不同的单位表示,例如天、小时、分钟、秒。它们可以是正数也可以是负数。
我们可以使用如下所示的各种参数创建 Timedelta 对象:
字符串
通过传递字符串字面量,我们可以创建一个 timedelta 对象。
import pandas as pd print pd.Timedelta('2 days 2 hours 15 minutes 30 seconds')
其 **输出** 如下:
2 days 02:15:30
整数
通过传递带有单位的整数值,参数创建一个 Timedelta 对象。
import pandas as pd print pd.Timedelta(6,unit='h')
其 **输出** 如下:
0 days 06:00:00
数据偏移量
数据偏移量,例如周、天、小时、分钟、秒、毫秒、微秒、纳秒,也可以用于构造。
import pandas as pd print pd.Timedelta(days=2)
其 **输出** 如下:
2 days 00:00:00
to_timedelta()
使用顶级 **pd.to_timedelta**,您可以将标量、数组、列表或序列从识别的 timedelta 格式/值转换为 Timedelta 类型。如果输入是 Series,它将构造 Series;如果输入是标量类型,它将构造标量;否则将输出 **TimedeltaIndex**。
import pandas as pd print pd.Timedelta(days=2)
其 **输出** 如下:
2 days 00:00:00
操作
您可以对 Series/DataFrame 进行操作,并通过对 **datetime64[ns]** Series 或 Timestamps 进行减法运算来构造 **timedelta64[ns]** Series。
现在让我们创建一个包含 Timedelta 和 datetime 对象的 DataFrame,并对其进行一些算术运算:
import pandas as pd s = pd.Series(pd.date_range('2012-1-1', periods=3, freq='D')) td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ]) df = pd.DataFrame(dict(A = s, B = td)) print df
其 **输出** 如下:
A B 0 2012-01-01 0 days 1 2012-01-02 1 days 2 2012-01-03 2 days
加法运算
import pandas as pd s = pd.Series(pd.date_range('2012-1-1', periods=3, freq='D')) td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ]) df = pd.DataFrame(dict(A = s, B = td)) df['C']=df['A']+df['B'] print df
其 **输出** 如下:
A B C 0 2012-01-01 0 days 2012-01-01 1 2012-01-02 1 days 2012-01-03 2 2012-01-03 2 days 2012-01-05
减法运算
import pandas as pd s = pd.Series(pd.date_range('2012-1-1', periods=3, freq='D')) td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ]) df = pd.DataFrame(dict(A = s, B = td)) df['C']=df['A']+df['B'] df['D']=df['C']+df['B'] print df
其 **输出** 如下:
A B C D 0 2012-01-01 0 days 2012-01-01 2012-01-01 1 2012-01-02 1 days 2012-01-03 2012-01-04 2 2012-01-03 2 days 2012-01-05 2012-01-07
Python Pandas - 分类数据
在实际应用中,数据经常包含重复的文本列。诸如性别、国家和代码之类的特征总是重复的。这些是分类数据的示例。
分类变量只能取有限的、通常是固定的可能值。除了固定长度外,分类数据可能具有顺序,但不能执行数值运算。分类数据是一种 Pandas 数据类型。
分类数据类型在以下情况下非常有用:
仅包含少量不同值的字符串变量。将此类字符串变量转换为分类变量可以节省一些内存。
变量的词法顺序与其逻辑顺序不同(“一”、“二”、“三”)。通过转换为分类变量并在类别上指定顺序,排序和最小/最大值将使用逻辑顺序而不是词法顺序。
作为其他 Python 库的信号,表明此列应被视为分类变量(例如,使用合适的统计方法或绘图类型)。
对象创建
分类对象可以通过多种方式创建。下面描述了不同的方法:
category
在 pandas 对象创建中将 dtype 指定为“category”。
import pandas as pd s = pd.Series(["a","b","c","a"], dtype="category") print s
其 **输出** 如下:
0 a 1 b 2 c 3 a dtype: category Categories (3, object): [a, b, c]
传递给 series 对象的元素数量为四个,但类别只有三个。在输出类别中观察到相同的情况。
pd.Categorical
使用标准 pandas Categorical 构造函数,我们可以创建一个类别对象。
pandas.Categorical(values, categories, ordered)
让我们来看一个例子:
import pandas as pd cat = pd.Categorical(['a', 'b', 'c', 'a', 'b', 'c']) print cat
其 **输出** 如下:
[a, b, c, a, b, c] Categories (3, object): [a, b, c]
让我们再来看一个例子:
import pandas as pd cat = cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a']) print cat
其 **输出** 如下:
[a, b, c, a, b, c, NaN] Categories (3, object): [c, b, a]
这里,第二个参数表示类别。因此,任何不在类别中的值都将被视为 **NaN**。
现在,让我们来看下面的例子:
import pandas as pd cat = cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'],ordered=True) print cat
其 **输出** 如下:
[a, b, c, a, b, c, NaN] Categories (3, object): [c < b < a]
逻辑上,顺序意味着 **a** 大于 **b**,**b** 大于 **c**。
描述
对分类数据使用 **.describe()** 命令,我们得到与 **type** 为字符串的 **Series** 或 **DataFrame** 类似的输出。
import pandas as pd import numpy as np cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"]) df = pd.DataFrame({"cat":cat, "s":["a", "c", "c", np.nan]}) print df.describe() print df["cat"].describe()
其 **输出** 如下:
cat s count 3 3 unique 2 2 top c c freq 2 2 count 3 unique 2 top c freq 2 Name: cat, dtype: object
获取类别的属性
**obj.cat.categories** 命令用于获取 **对象的类别**。
import pandas as pd import numpy as np s = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"]) print s.categories
其 **输出** 如下:
Index([u'b', u'a', u'c'], dtype='object')
**obj.ordered** 命令用于获取对象的顺序。
import pandas as pd import numpy as np cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"]) print cat.ordered
其 **输出** 如下:
False
该函数返回 **false**,因为我们没有指定任何顺序。
重命名类别
重命名类别是通过将新值赋给 **series.cat.categories** 属性来完成的。
import pandas as pd s = pd.Series(["a","b","c","a"], dtype="category") s.cat.categories = ["Group %s" % g for g in s.cat.categories] print s.cat.categories
其 **输出** 如下:
Index([u'Group a', u'Group b', u'Group c'], dtype='object')
初始类别 **[a,b,c]** 由对象的 **s.cat.categories** 属性更新。
追加新类别
使用 Categorical.add.categories() 方法,可以追加新的类别。
import pandas as pd s = pd.Series(["a","b","c","a"], dtype="category") s = s.cat.add_categories([4]) print s.cat.categories
其 **输出** 如下:
Index([u'a', u'b', u'c', 4], dtype='object')
删除类别
使用 **Categorical.remove_categories()** 方法,可以删除不需要的类别。
import pandas as pd s = pd.Series(["a","b","c","a"], dtype="category") print ("Original object:") print s print ("After removal:") print s.cat.remove_categories("a")
其 **输出** 如下:
Original object: 0 a 1 b 2 c 3 a dtype: category Categories (3, object): [a, b, c] After removal: 0 NaN 1 b 2 c 3 NaN dtype: category Categories (2, object): [b, c]
分类数据的比较
在三种情况下可以将分类数据与其他对象进行比较:
将相等性(== 和 !=)与与分类数据长度相同的列表状对象(列表、Series、数组……)进行比较。
当 ordered==True 且类别相同时,将分类数据与另一个分类 Series 进行所有比较(==、!=、>、>=、< 和 <=)。
将分类数据与标量进行所有比较。
让我们来看下面的例子:
import pandas as pd cat = pd.Series([1,2,3]).astype("category", categories=[1,2,3], ordered=True) cat1 = pd.Series([2,2,2]).astype("category", categories=[1,2,3], ordered=True) print cat>cat1
其 **输出** 如下:
0 False 1 False 2 True dtype: bool
Python Pandas - 可视化
基本绘图:plot
Series 和 DataFrame 上的此功能只是 **matplotlib** **库 plot()** 方法的一个简单包装器。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10,4),index=pd.date_range('1/1/2000', periods=10), columns=list('ABCD')) df.plot()
其 **输出** 如下:
如果索引包含日期,它将调用 **gct().autofmt_xdate()** 以格式化 x 轴,如上图所示。
我们可以使用 **x** 和 **y** 关键字绘制一列与另一列的关系图。
绘图方法允许使用少数几种除默认线图以外的绘图样式。这些方法可以作为 **plot()** 的 kind 关键字参数提供。这些包括:
- bar 或 barh 用于条形图
- hist 用于直方图
- box 用于箱线图
- 'area' 用于面积图
- 'scatter' 用于散点图
条形图
现在让我们通过创建一个条形图来看看什么是条形图。条形图可以通过以下方式创建:
import pandas as pd import numpy as np df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d') df.plot.bar()
其 **输出** 如下:
要生成堆叠条形图,请 **传递 stacked=True**:
import pandas as pd df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d') df.plot.bar(stacked=True)
其 **输出** 如下:
要获取水平条形图,请使用 **barh** 方法:
import pandas as pd import numpy as np df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d') df.plot.barh(stacked=True)
其 **输出** 如下:
直方图
可以使用 **plot.hist()** 方法绘制直方图。我们可以指定箱数。
import pandas as pd import numpy as np df = pd.DataFrame({'a':np.random.randn(1000)+1,'b':np.random.randn(1000),'c': np.random.randn(1000) - 1}, columns=['a', 'b', 'c']) df.plot.hist(bins=20)
其 **输出** 如下:
要为每一列绘制不同的直方图,请使用以下代码:
import pandas as pd import numpy as np df=pd.DataFrame({'a':np.random.randn(1000)+1,'b':np.random.randn(1000),'c': np.random.randn(1000) - 1}, columns=['a', 'b', 'c']) df.diff.hist(bins=20)
其 **输出** 如下:
箱线图
可以通过调用 **Series.box.plot()** 和 **DataFrame.box.plot()**,或者 **DataFrame.boxplot()** 来绘制箱线图,以可视化每一列中值的分布。
例如,这是一个箱线图,它表示在 [0,1) 上进行 10 次观察的 5 次均匀随机变量试验。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.rand(10, 5), columns=['A', 'B', 'C', 'D', 'E']) df.plot.box()
其 **输出** 如下:
面积图
可以使用 **Series.plot.area()** 或 **DataFrame.plot.area()** 方法创建面积图。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd']) df.plot.area()
其 **输出** 如下:
散点图
可以使用 **DataFrame.plot.scatter()** 方法创建散点图。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.rand(50, 4), columns=['a', 'b', 'c', 'd']) df.plot.scatter(x='a', y='b')
其 **输出** 如下:
饼图
可以使用 **DataFrame.plot.pie()** 方法创建饼图。
import pandas as pd import numpy as np df = pd.DataFrame(3 * np.random.rand(4), index=['a', 'b', 'c', 'd'], columns=['x']) df.plot.pie(subplots=True)
其 **输出** 如下:
Python Pandas - I/O 工具
**Pandas I/O API** 是一组顶级读取器函数,类似于 **pd.read_csv()**,通常返回 Pandas 对象。
用于读取文本文件(或平面文件)的两个主要函数是 **read_csv()** 和 **read_table()**。它们都使用相同的解析代码将表格数据智能地转换为 **DataFrame** 对象:
pandas.read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None
pandas.read_csv(filepath_or_buffer, sep='\t', delimiter=None, header='infer', names=None, index_col=None, usecols=None
以下是 **csv** 文件数据的样子:
S.No,Name,Age,City,Salary 1,Tom,28,Toronto,20000 2,Lee,32,HongKong,3000 3,Steven,43,Bay Area,8300 4,Ram,38,Hyderabad,3900
将此数据另存为 **temp.csv** 并对其进行操作。
S.No,Name,Age,City,Salary 1,Tom,28,Toronto,20000 2,Lee,32,HongKong,3000 3,Steven,43,Bay Area,8300 4,Ram,38,Hyderabad,3900
将此数据另存为 **temp.csv** 并对其进行操作。
read.csv
**read.csv** 从 csv 文件读取数据并创建 DataFrame 对象。
import pandas as pd df=pd.read_csv("temp.csv") print df
其 **输出** 如下:
S.No Name Age City Salary 0 1 Tom 28 Toronto 20000 1 2 Lee 32 HongKong 3000 2 3 Steven 43 Bay Area 8300 3 4 Ram 38 Hyderabad 3900
自定义索引
这指定了 csv 文件中的一列,可以使用 **index_col** 来自定义索引。
import pandas as pd df=pd.read_csv("temp.csv",index_col=['S.No']) print df
其 **输出** 如下:
S.No Name Age City Salary 1 Tom 28 Toronto 20000 2 Lee 32 HongKong 3000 3 Steven 43 Bay Area 8300 4 Ram 38 Hyderabad 3900
转换器
列的 **dtype** 可以作为字典传递。
import pandas as pd df = pd.read_csv("temp.csv", dtype={'Salary': np.float64}) print df.dtypes
其 **输出** 如下:
S.No int64 Name object Age int64 City object Salary float64 dtype: object
默认情况下,Salary 列的 **dtype** 是 **int**,但结果显示为 **float**,因为我们已显式转换了类型。
因此,数据看起来像浮点数:
S.No Name Age City Salary 0 1 Tom 28 Toronto 20000.0 1 2 Lee 32 HongKong 3000.0 2 3 Steven 43 Bay Area 8300.0 3 4 Ram 38 Hyderabad 3900.0
header_names
使用 names 参数指定 header 的名称。
import pandas as pd df=pd.read_csv("temp.csv", names=['a', 'b', 'c','d','e']) print df
其 **输出** 如下:
a b c d e 0 S.No Name Age City Salary 1 1 Tom 28 Toronto 20000 2 2 Lee 32 HongKong 3000 3 3 Steven 43 Bay Area 8300 4 4 Ram 38 Hyderabad 3900
观察到,header 名称已附加了自定义名称,但文件中的 header 尚未删除。现在,我们使用 header 参数将其删除。
如果 header 不在第一行,则将行号传递给 header。这将跳过前面的行。
import pandas as pd df=pd.read_csv("temp.csv",names=['a','b','c','d','e'],header=0) print df
其 **输出** 如下:
a b c d e 0 S.No Name Age City Salary 1 1 Tom 28 Toronto 20000 2 2 Lee 32 HongKong 3000 3 3 Steven 43 Bay Area 8300 4 4 Ram 38 Hyderabad 3900
skiprows
skiprows 跳过指定数量的行。
import pandas as pd df=pd.read_csv("temp.csv", skiprows=2) print df
其 **输出** 如下:
2 Lee 32 HongKong 3000 0 3 Steven 43 Bay Area 8300 1 4 Ram 38 Hyderabad 3900
Python Pandas - 稀疏数据
当任何与特定值匹配的数据(NaN/缺失值,尽管可以选择任何值)被省略时,稀疏对象会被“压缩”。一个特殊的 SparseIndex 对象跟踪数据被“稀疏化”的位置。在一个例子中,这将更有意义。所有标准的 Pandas 数据结构都应用 **to_sparse** 方法:
import pandas as pd import numpy as np ts = pd.Series(np.random.randn(10)) ts[2:-2] = np.nan sts = ts.to_sparse() print sts
其 **输出** 如下:
0 -0.810497 1 -1.419954 2 NaN 3 NaN 4 NaN 5 NaN 6 NaN 7 NaN 8 0.439240 9 -1.095910 dtype: float64 BlockIndex Block locations: array([0, 8], dtype=int32) Block lengths: array([2, 2], dtype=int32)
稀疏对象的存在是为了提高内存效率。
现在让我们假设您有一个大型 NA DataFrame 并执行以下代码:
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10000, 4)) df.ix[:9998] = np.nan sdf = df.to_sparse() print sdf.density
其 **输出** 如下:
0.0001
任何稀疏对象都可以通过调用 **to_dense** 转换回标准密集形式:
import pandas as pd import numpy as np ts = pd.Series(np.random.randn(10)) ts[2:-2] = np.nan sts = ts.to_sparse() print sts.to_dense()
其 **输出** 如下:
0 -0.810497 1 -1.419954 2 NaN 3 NaN 4 NaN 5 NaN 6 NaN 7 NaN 8 0.439240 9 -1.095910 dtype: float64
稀疏 Dtypes
稀疏数据应与其密集表示具有相同的 dtype。目前,支持 **float64、int64** 和 **booldtypes**。根据原始 **dtype,fill_value 默认值** 会发生变化:
**float64** − np.nan
**int64** − 0
**bool** − False
让我们执行以下代码来了解这一点:
import pandas as pd import numpy as np s = pd.Series([1, np.nan, np.nan]) print s s.to_sparse() print s
其 **输出** 如下:
0 1.0 1 NaN 2 NaN dtype: float64 0 1.0 1 NaN 2 NaN dtype: float64
Python Pandas - 警告和陷阱
Caveats 表示警告,gotcha 表示未发现的问题。
在 Pandas 中使用 If/Truth 语句
Pandas 遵循 numpy 的约定,在尝试将某些内容转换为布尔值 (bool) 时会引发错误。这发生在使用布尔运算符 `if` 或 `when`,以及 `and`、`or` 或 `not` 的情况下。结果应该是什么并不明确。因为它不是零长度,所以应该是 True 吗?因为存在 False 值,所以应该是 False 吗?这不明确,因此 Pandas 会引发ValueError。
import pandas as pd if pd.Series([False, True, False]): print 'I am True'
其 **输出** 如下:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool() a.item(),a.any() or a.all().
在 `if` 条件中,不清楚该如何处理。该错误提示是否应该使用 `None` 或其中任何一个。
import pandas as pd if pd.Series([False, True, False]).any(): print("I am any")
其 **输出** 如下:
I am any
要在布尔上下文中评估单元素 Pandas 对象,请使用 `.bool()` 方法。
import pandas as pd print pd.Series([True]).bool()
其 **输出** 如下:
True
按位布尔运算
像 `==` 和 `!=` 这样的按位布尔运算符将返回一个布尔序列,而这几乎总是需要的。
import pandas as pd s = pd.Series(range(5)) print s==4
其 **输出** 如下:
0 False 1 False 2 False 3 False 4 True dtype: bool
isin 操作
这将返回一个布尔序列,显示 Series 中的每个元素是否完全包含在传递的值序列中。
import pandas as pd s = pd.Series(list('abc')) s = s.isin(['a', 'c', 'e']) print s
其 **输出** 如下:
0 True 1 False 2 True dtype: bool
重新索引与 ix 的陷阱
许多用户会发现自己使用ix 索引功能作为从 Pandas 对象中选择数据的简洁方法。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three', 'four'],index=list('abcdef')) print df print df.ix[['b', 'c', 'e']]
其 **输出** 如下:
one two three four a -1.582025 1.335773 0.961417 -1.272084 b 1.461512 0.111372 -0.072225 0.553058 c -1.240671 0.762185 1.511936 -0.630920 d -2.380648 -0.029981 0.196489 0.531714 e 1.846746 0.148149 0.275398 -0.244559 f -1.842662 -0.933195 2.303949 0.677641 one two three four b 1.461512 0.111372 -0.072225 0.553058 c -1.240671 0.762185 1.511936 -0.630920 e 1.846746 0.148149 0.275398 -0.244559
当然,在这种情况下,这与使用reindex方法完全等效。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three', 'four'],index=list('abcdef')) print df print df.reindex(['b', 'c', 'e'])
其 **输出** 如下:
one two three four a 1.639081 1.369838 0.261287 -1.662003 b -0.173359 0.242447 -0.494384 0.346882 c -0.106411 0.623568 0.282401 -0.916361 d -1.078791 -0.612607 -0.897289 -1.146893 e 0.465215 1.552873 -1.841959 0.329404 f 0.966022 -0.190077 1.324247 0.678064 one two three four b -0.173359 0.242447 -0.494384 0.346882 c -0.106411 0.623568 0.282401 -0.916361 e 0.465215 1.552873 -1.841959 0.329404
根据这一点,有些人可能会得出结论,ix 和reindex是 100% 等效的。除了整数索引的情况外,这是正确的。例如,上述操作可以另一种方式表达为:
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three', 'four'],index=list('abcdef')) print df print df.ix[[1, 2, 4]] print df.reindex([1, 2, 4])
其 **输出** 如下:
one two three four a -1.015695 -0.553847 1.106235 -0.784460 b -0.527398 -0.518198 -0.710546 -0.512036 c -0.842803 -1.050374 0.787146 0.205147 d -1.238016 -0.749554 -0.547470 -0.029045 e -0.056788 1.063999 -0.767220 0.212476 f 1.139714 0.036159 0.201912 0.710119 one two three four b -0.527398 -0.518198 -0.710546 -0.512036 c -0.842803 -1.050374 0.787146 0.205147 e -0.056788 1.063999 -0.767220 0.212476 one two three four 1 NaN NaN NaN NaN 2 NaN NaN NaN NaN 4 NaN NaN NaN NaN
重要的是要记住,reindex 仅是严格的标签索引。在索引包含整数和字符串等病态情况下,这可能会导致一些潜在的意外结果。
Python Pandas - 与 SQL 的比较
由于许多潜在的 Pandas 用户都熟悉 SQL,因此本页旨在提供一些关于如何使用 pandas 执行各种 SQL 操作的示例。
import pandas as pd url = 'https://raw.github.com/pandasdev/ pandas/master/pandas/tests/data/tips.csv' tips=pd.read_csv(url) print tips.head()
其 **输出** 如下:
total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4
SELECT
在 SQL 中,选择是使用逗号分隔的列列表(或 `*` 选择所有列)来完成的。
SELECT total_bill, tip, smoker, time FROM tips LIMIT 5;
在 Pandas 中,列选择是通过将列名列表传递给您的 DataFrame 来完成的。
tips[['total_bill', 'tip', 'smoker', 'time']].head(5)
让我们检查完整的程序。
import pandas as pd url = 'https://raw.github.com/pandasdev/ pandas/master/pandas/tests/data/tips.csv' tips=pd.read_csv(url) print tips[['total_bill', 'tip', 'smoker', 'time']].head(5)
其 **输出** 如下:
total_bill tip smoker time 0 16.99 1.01 No Dinner 1 10.34 1.66 No Dinner 2 21.01 3.50 No Dinner 3 23.68 3.31 No Dinner 4 24.59 3.61 No Dinner
在不带列名列表的情况下调用 DataFrame 将显示所有列(类似于 SQL 的 `*`)。
WHERE
在 SQL 中,过滤是通过 WHERE 子句完成的。
SELECT * FROM tips WHERE time = 'Dinner' LIMIT 5;
DataFrame 可以通过多种方式进行过滤;其中最直观的是使用布尔索引。
tips[tips['time'] == 'Dinner'].head(5)
让我们检查完整的程序。
import pandas as pd url = 'https://raw.github.com/pandasdev/ pandas/master/pandas/tests/data/tips.csv' tips=pd.read_csv(url) print tips[tips['time'] == 'Dinner'].head(5)
其 **输出** 如下:
total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4
上面的语句将一个 True/False 对象的序列传递给 DataFrame,返回所有值为 True 的行。
GroupBy
此操作获取整个数据集中每个组中记录的数量。例如,查询获取按性别留下的消费小费数量:
SELECT sex, count(*) FROM tips GROUP BY sex;
Pandas 等效项将是:
tips.groupby('sex').size()
让我们检查完整的程序。
import pandas as pd url = 'https://raw.github.com/pandasdev/ pandas/master/pandas/tests/data/tips.csv' tips=pd.read_csv(url) print tips.groupby('sex').size()
其 **输出** 如下:
sex Female 87 Male 157 dtype: int64
前 N 行
SQL 使用LIMIT返回前 n 行。
SELECT * FROM tips LIMIT 5 ;
Pandas 等效项将是:
tips.head(5)
让我们检查完整的示例。
import pandas as pd url = 'https://raw.github.com/pandas-dev/pandas/master/pandas/tests/data/tips.csv' tips=pd.read_csv(url) tips = tips[['smoker', 'day', 'time']].head(5) print tips
其 **输出** 如下:
smoker day time 0 No Sun Dinner 1 No Sun Dinner 2 No Sun Dinner 3 No Sun Dinner 4 No Sun Dinner
这些是我们之前章节中学习的 Pandas 库中比较的几个基本操作。