Pandas

Pandas

目录
一、Pandas基础
二、Pandas三大数据结构
1.Series
2.DataFrame
3.Index
三、数据取值与选择
四、数值运算
五、缺失值处理
六、层级索引
七、合并数据集:Concat与Append操作
八、合并数据集:合并与连接
九、累计与分组
十、数据透视表
十一、向量化字符串操作
十二、时间序列处理
十三、高性能

一、Pandas基础

1.安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ pandas

2.库导入

import numpy as np
import pandas as pd

二、Pandas三大数据结构

1.Series

(1)Series是通用的NumPy数组

Series对象和NumPy数组的差异:NumPy数组通过隐式定义的整数索引获取数值,而Pandas的Series对象使用一种显式定义的索引与数值相关联。

data = pd.Series([0.25, 0.5, 0.75, 1.0], index=['a', 'b', 'c', 'd'])

(2)Series是特殊的字典

population_dict = {'California': 38332521, 
                   'Texas': 26448193, 
                   'New York': 19651127, 
                   'Florida': 19552860, 
                   'Illinois': 12882135}
population = pd.Series(population_dict)

Series比字典强大,支持数组形式的操作:
如:切片

population['New York': 'Illinois']

(3)创建Series对象

pd.Series(data, [index])
  • 1.data可以是列表或NumPy数组
pd.Series([2, 4, 6])
  • 2.data可以是一个标量
    创建Series对象时会将data重复填充到每个索引上
pd.Series(5, index=[100, 200, 300])
  • 3.data可以是一个字典
pd.Series({'a':1, 'b':2, 'c':3})

2.DataFrame

样例用例数据

population_dict = {'California': 38332521, 
                   'Texas': 26448193, 
                   'New York': 19651127, 
                   'Florida': 19552860, 
                   'Illinois': 12882135}
area_dict = {'California': 423967, 
             'Texas': 695662, 
             'New York': 141297, 
             'Florida': 170312, 
             'Illinois': 149995}
population = pd.Series(population_dict)
area = pd.Series(area_dict)
states = pd.DataFrame({'population': population, 'area': area})

(1)DataFrame是通用的NumPy数组

(2)DataFrame是特殊的字典

普通字典是一个键映射一个值,而DataFrame是一列映射一个Series对象。


(3)创建DataFrame对象

  • 1.通过单个Series对象创建
pd.DataFrame(Series对象, columns=['索引列名称'])

示例:

pd.DataFrame(population, columns=['population'])
  • 2.通过字典列表创建
data = [{'a': i, 'b': 2 * i} for i in range(3)]
pd.DataFrame(data)

如果字典中有些键不存在,Pandas会用缺失值NaN来填充:

pd.DataFrame([{'a': 1, 'b': 2}, {'b': 3, 'c': 4}])
  • 3.通过Series对象字典创建
pd.DataFrame({'population': population, 'area': area})

3.Index

(1)Index是不可变数组

  • Index对象拥有与NumPy数组相似的属性


  • Index对象的不可变特征使得多个Series和DataFrame之间进行索引共享时更加安全


(2)Index是有序集合

三、数据取值与选择

1.Series数据选择方法

示例用例数据:

data = pd.Series([0.25, 0.5, 0.75, 1.0], index=['a', 'b', 'c', 'd'])

(1)将Series看作字典

(2)将Series看作一维数组

Series具有和NumPy数组一样的数组数据选择功能(索引、掩码、花哨索引等)

# 将显式索引作为切片
data['a': 'c']
# 将隐式整数索引作为切片
data[1:3]


注意:显式索引切片结果包含最后一个索引,隐式索引切片结果不包含最后一个索引。

# 掩码
data[(data > 0.3) & (data < 0.8)]
# 花哨索引
data[['a', 'e']]

(3)索引器(loc、iloc、ix)

示例用例数据:

data = pd.Series(['a', 'b', 'c'], index=[1, 3, 5])

①loc显式索引

②iloc隐式索引

③ix混合索引

2.DataFrame数据选择方法

示例用例数据:

area_dict = {'California': 423967, 
             'Texas': 695662, 
             'New York': 141297, 
             'Florida': 170312, 
             'Illinois': 149995}
population_dict = {'California': 38332521, 
                   'Texas': 26448193, 
                   'New York': 19651127, 
                   'Florida': 19552860, 
                   'Illinois': 12882135}
area = pd.Series(area_dict)
pop = pd.Series(population_dict)

data = pd.DataFrame({'area': area, 'pop': pop})

(1)将DataFrame看作字典

(2)将DataFrame看作二维数组

  • 使用索引器取值


  • 任何用于处理NumPy形式数据的方法,都可以用于这些索引器,如:掩码、花哨索引
  • 任何一种取值方法都可以用于修改数据


    image.png

(3)其他取值方法

  • 对单个标签取值选择列,对多个标签切片选择行
  • 切片也可以直接使用行数实现(隐式索引)


  • 掩码操作可以对每一行进行过滤


四、数值运算

常见Python运算符与Pandas方法映射关系

Python运算符 Pandas方法
+ add()
- sub()、subtract()
* mul()、multiply()
/ truediv()、div()、divide()
// floordiv()
% mod()
** pow()

1.通用函数:保留索引

通用函数运算结果会保留索引

  • Series


  • DataFrame


2.通用函数:索引对齐

(1)Series索引对齐

  • 运算结果数组的索引是两个数组索引的并集。
  • 对于缺失位置的数据,Pandas会用NaN填充,表示“此处没有数据”。


  • 如果NaN值不是想要的结果,可以用通用函数的fill_value参数来指定。


(2)DataFrame索引对齐

  • 在计算两个DataFrame时,索引对齐规则同样会出现在共同列(并集)中。


  • df.unstack()方法可以将二维数据拆为一维数据


3.通用函数:DataFrame与Series的运算

  • 二维数组减去一行会按行计算,Pandas减去一行默认也是按行计算。
  • 通过通用函数的axis参数,可以指定计算的方式。


  • DataFrame和Series运算时,结果的索引也会自动对齐。


五、缺失值处理

Pandas采用标签值表示缺失值
有两种方式:

1.浮点数据类型NaN
2.Python对象类型None

1.None:Pyhton对象类型的缺失值(object对象类型)

  • 只能用于NumPy/Pandas数组类型中的'object'类型。


  • object类型的数据会消耗更多的资源。

    注意:无法对包含None的数组进行累计操作。

2.NaN:数值类型的缺失值(浮点型)

  • NaN是一种按照IEEE浮点数标准设计、在任何系统中都兼容的特殊浮点数。


  • 任何数与NaN进行运算结果都是NaN。


    =

3.Pandas中None与NaN的差异

  • Pandas将None与NaN看作是等价可交换的,在适当的时候会将两者进行替换。
  • Pandas会将没有标签值的数据类型自动转换为NaN。


  • Pandas会将含缺失值的整型数组转换为浮点类型,并且将None转换为NaN。



    如果是DataFrame,则会将含缺失值的列转换为浮点类型。

4.处理缺失值

Pandas对不同类型缺失值的转换规则

类型 缺失值转换规则 NA标签值
floating浮点型 无变化 np.nan
object对象类型 无变化 None或np.nan
integer整数类型 强制转换为float64 np.nan
boolean布尔类型 强制转换为object None或np.nan

注意:Pandas中字符串类型的数据通常使用object类型存储的。

(1)发现缺失值

isnull()方法和data.notnull()方法:创建一个布尔类型的掩码标签

data = pd.Series([1, np.nan, 'hello', None])
data.isnull()
data.notnull()

(2)剔除缺失值

data.dropna()
  • 1.Series
    dropna()方法返回一个去除缺失值的数据。


  • 2.DataFrame
    默认情况下剔除包含缺失值的整行数据。



    可以指定删除含缺失值的整列数据。

df.dropna(axis=1)
df.dropna(axis='columns')
  • 3.还可以自定删除条件
    ①通过how参数定义删除规则
df.dropna(axis=删除轴, how='删除规则')

②通过thresh参数设置判定是否删除的缺失值数量

df.dropna(axis=删除轴, thresh=最小缺失值数量)

(3)填充缺失值

①指定值填充

data.fillna(填充值)

②前向填充

用缺失值前面的有效值来从前往后填充(forward-fill)

data.fillna(method='ffill')

③后向填充

用缺失值后面的有效值来从后往前填充(back-fill)

data.fillna(method='bfill')
  • DataFrame填充方法与Series类似,只是在填充式需要设置坐标轴参数axis。若不指定则默认按行填充(用上一行的有效值填充下一行的缺失值)。


六、层级索引

目录
1.多级索引Series
2.多级索引的创建方法
3.多级索引的取值与切片
4.多级索引行列转换
5.多级索引的数据累计方法

1.多级索引Series

示例用例数据:

index = [('California', 2000), ('California', 2010), ('New York', 2000), ('New York', 2010), ('Texas', 2000), ('Texas', 2010)]
populations = [33871648, 37253956, 18976457, 19378102, 20851820, 25145561]
pop = pd.Series(populations, index=index)

(1)普通方法(使用普通索引)


缺点:在查询数据时需使用循环迭代,不够简洁(在处理大量数据时效率也不高)。

(2)Pandas多级索引

index = [索引元组列表]
index = pd.MultiIndex.from_tuples(index)
data = data.reindex(index)

通过多级索引可以方便地查询数据:


(3)高维数据的多级索引

  • 1.unstack()方法可以将一个拥有多级索引的Series转换为普通索引的DataFrame。
  • 2.stack()方法可以将使用普通索引的DataFrame转换为拥有多级索引的Series。
data_df = data.unstack()
data = data_df.stack()
  • 增加一列


2.多级索引的创建方法

  • 为Series或DataFrame创建多级索引最直接的办法就是讲index参数设置为至少二维的索引数组。


(1)显式地创建多级索引


显式多级索引创建完成以后,可以通过index参数指定,或者通过reindex()方法更新Series或DataFrame的索引。

(2)多级索引的等级名称

可以在构造MultiIndex时通过参数names,或在构造完成后通过MultiIndex对象的names属性来指定索引的等级名称。


(3)多级列索引

# 多级行列索引
index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]], names=['year', 'visit'])
columns = pd.MultiIndex.from_product([['Bob', 'Guido', 'Sue'], ['HR', 'Temp']], names=['subject', 'type'])

# 模拟数据
data = np.round(np.random.randn(4, 6), 1)
data[:, ::2] *= 10
data += 37

# 创建DataFrame
health_data = pd.DataFrame(data, index=index, columns=columns)
health_data

3.多级索引的取值与切片

(1)Series多级索引

  • 1.如果只取最高级索引,获取的结果是一个新的Series,未被选中的低层索引值会被保留。


  • 2.如果想要直接使用较低层级的索引取值,第一层级的索引可以用空切片。


  • 3.多级索引同样支持花哨索引、掩码等操作


(2)DataFrame多级索引

  • 可以使用loc|iloc选择多行多列


  • 在元组中使用切片会引起错误,因此Pandas使用IndexSlice对象进行切片操作


4.多级索引行列转换

(1)有序索引和无序索引

多级索引局部切片要求MultiIndex的各级索引是有序的。


(2)索引stack与unstack

(3)索引的设置与重置

  • 1.使用name参数为列设置名称(将多级索引变成多列数据)


  • 2.将多列数据设置为多级索引


5.多级索引的数据累计方法

七、合并数据集:Concat与Append操作

1.知识回顾:NumPy数组合并

2.pd.concat()方法

示例用例方法:

def make_df(cols, ind):
    data = {c:[str(c) + str(i) for i in ind] for c in cols}
    print(data)
    return pd.DataFrame(data, ind)
  • 1.Series


  • 2.DataFrame



(1)索引重复

  • 合并时,pd.concat方法会保留重复的索引


处理重复索引
1.捕捉索引重复异常:设置vertify_integrity=True,合并时若出现重复索引则触发异常。
2.忽略重复索引:设置ignore_index=True,合并时则将会创建一个新的整数索引。


(2)类似join的合并

示例用例数据:

df5 = make_df('ABC', [1, 2])
df6 = make_df('BCD', [3, 4])
print(df5, '\n\n', df6)
pd.concat([df5, df6], sort=False)


(3)append()方法


注意:append()方法合并会创建新对象,效率较低。

八、合并数据集:合并与连接

目录
1.数据连接的类型
2.设置数据合并的键
3.设置数据连接的集合操作规则
4.设置重复列名后缀名

1.数据连接的类型

pd.merge()实现三种类型的数据连接(一对一、一对多、多对多)

(1)一对一连接

  • pd.merge()方法会发现两个DataFrame都有的列,并会自动以这列作为键进行连接,生成一个新的DataFrame。
df1 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'], 'group': ['Accounting', 'Engineering', 'Engineering', 'HR']})
df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'], 'hire_date': [2004, 2008, 2012, 2014]})
df3 = pd.merge(df1, df2)

(2)一对多连接

一个group对应多个employee:


(3)多对多连接

一个group对应多个employee,一个group对应多个skills:



2.设置数据合并的键

(1)on参数

  • 通过pd.merge()方法的on参数指定关联时的键
pd.merge(df1, df2, on='参照键')


注意:on参数只能在两个DataFrame有相同的列名时使用。

(2)left_on与right_on参数


(3)left_index与right_index参数

  • 通过索引连接
df1a = df1.set_index('employee')
df2a = df2.set_index('employee')
pd.merge(df1a, df2a, left_index=True, right_index=True)

  • join()方法也可以按照索引进行连接


  • 可以通过 left_index|right_on或者left_on|right_index参数组合,将列和索引混合使用


3.设置数据连接的集合操作规则

用例数据:

df6 = pd.DataFrame({'name': ['Peter', 'Paul', 'Mary'], 'food': ['fish', 'beans', 'bread']}, columns=['name', 'food'])
df7 = pd.DataFrame({'name': ['Mary', 'Joseph'], 'drink': ['wine', 'beer']}, columns=['name', 'drink'])
  • 默认情况下pd.merge()方法采用内连接


  • 通过merge()方法的how参数指定连接规则



4.设置重复列名后缀名

用例数据:

df8 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'], 'rank': [1, 2, 3, 4]})
df9 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'], 'rank': [3, 1, 2, 4]})
  • 通过suffixes参数指定重复列名后缀名


九、累计与分组

1.累计

Series和DataFrame支持所有的NumPy累计操作

Pandas常见累计方法

指标 描述
count() 计数项
first()、last() 第一项、最后一项
mean()、median() 均值、中位数
min()、max() 最小值、最大值
std()、var() 标准差、方差
mad() 均值绝对偏差
prod() 所有项乘积
sum() 所有项求和

示例:


  • Series和DataFrame支持所有的NumPy累计操作


  • 查看常见的统计值
df.describe()

2.分组:GroupBy

(1)GroupBy过程:分割、应用、组合

GroupBy操作可视化过程

groupby():传入要分割的名称,返回一个DataFrameGroupBy对象,可以进行进一步操作。

(2)GroupBy对象

groupby对象主要有以下四种操作:

aggregate、filter、transform、apply(累计、过滤、转换、应用)

用例数据:

import seaborn as sns
planets = sns.load_dataset('planets')
# 查看前五行数据
planets.head()
# 查看后五行数据
planets.tail()
# 查看数据描述信息
planets.describe()

①按列取值

②按组迭代

③调用方法

  • 调用方法可以让任何不由GroupBy对象直接实现的方法直接应用的每一组


(3)累计、过滤、转换、应用

用例数据:

rng = np.random.RandomState(0)
df = pd.DataFrame({'key': ['A', 'B', 'C', 'A', 'B', 'C'], 'data1': range(6), 'data2': rng.randint(0, 10, 6)}, columns=['key', 'data1', 'data2'])

①累计:aggregate()方法

  • aggregate()方法支持复杂的累计操作,如:字符串、函数、函数列表等


  • aggregate()方法可以传入一个字典,为不同的列指定不同的累计方法


②过滤:filter()方法

过滤操作:按照分组属性,丢弃若干数据(返回True保留数据,返回False过滤掉数据)。

③转换:transform()方法

转换:累计操作是对组内全量数据进行缩减的结果,而转换操作会返回一个新的全量数据。

④应用:apply()方法

apply()方法可以在每个组上应用任意方法, 输入一个DataFrame,返回一个Pandas对象(Series或DataFrame)或一个标量(scalar)。

(4)设置分割的键

①将列表、数组、Series、索引作为分组键

  • 分组键可以是长度与DataFrame匹配的任意Series或列表


②用字典或Series将索引映射到分组名称

df2 = df.set_index('key')
mapping = {'A': 'vower', 'B': 'consonant', 'C': 'consonant'}
df2.groupby(mapping).sum()


注意:索引的值要与字典的键保持统一。

③任意Python函数

  • 可以将任意Python函数传入groupby,函数映射到索引


  • 将函数作为分组键时,会修改函数传入索引列的值,如果没有定义索引,就会传入隐式索引的值



④多个有效键构成的列表

  • 只要是有效的键就可以组合起来进行分组


(5)分组案例

十、数据透视表

用例数据:

import seaborn as sns
titanic = sns.load_dataset('titanic')

1.手工制作数据透视表

2.数据透视表语法

pivot_table()方法:数据透视表

# 两条语句等效
titanic.groupby(['sex', 'class'])['survived'].aggregate('mean').unstack()
titanic.pivot_table('survived', index='sex', columns='class')

(1)多级数据透视表

  • 数据透视表中的分组可以通过各种参数指定多个等级


(2)其他数据透视表选项

  • 通过字典为不同列指定不同的累计函数
titanic.pivot_table(index='sex', columns='class', aggfunc={'survived': sum, 'fare': 'mean'})
  • margins_name参数:用来指定总数行的名称


十一、向量化字符串操作

1.Pandas字符串操作

Series和Index对象提供了str属性,可以方便地实现对字符串的操作,并且正确地处理缺失值。


2.Pandas字符串方法列表

(1)与Python字符串方法相似的方法

几乎所有Python内置的字符串方法都被复制到Pandas的向量化字符串方法中。
注意:这些方法的返回值可能与Python内置函数不同。
示例:

(2)正则表达式方法

Pandas向量化字符串方法与Python标准库re模块函数对应关系

方法 描述
match() 对每个元素调用re.match(),返回布尔类型值
extract() 对每个元素调用re.match(),返回匹配的字符串组(groups)
findall() 对每个元素调用re.findall()
replace() 用正则模式替换字符串
contains() 对每个元素调用re.search(),返回布尔类型值
count() 统计符合正则模式的字符串数量
split() 等价于str.split(),支持正则表达式
rsplit() 等价于str.rsplit(),支持正则表达式

示例:



(3)其他字符串方法

方法 描述
get() 获取元素索引位置上的值,索引从0开始
slice() 对元素进行切片取值
slice_replace() 对元素进行切片替换
cat() 连接字符串(此方法功能复杂,建议阅读文档)
repeat() 重复元素
normalize() 将字符串转换为Unicode规范格式
pad() 在字符串的左边、右边或两边增加空格
wrap() 将字符串按照指定的宽度换行
join() 用分隔符连接Series的每个元素
get_dummies() 按照分隔符提取每个元素的dummy变量,转换为独热(one-hot)编码的DataFrame

①向量化字符串取值与切片操作

  • 切片操作


  • 取值操作


②指标变量

# A=出生在美国
# B=出生在英国
# C=喜欢奶酪
# D=喜欢午餐肉
full_monte = pd.DataFrame({'name': monte, 'info': ['B|C|D', 'B|D', 'A|C', 'B|D', 'B|C', 'B|C|D']})
  • 独热编码
# 快速将指标变量转换为独热编码
full_monte['info'].str.get_dummies('|')

十二、时间序列处理

基本概念

  • 时间戳:表示某个具体的时间点
  • 时间间隔与周期:表示开始时间点与结束时间点之间的时间长度
  • 时间增量(持续时间):表示精确的时间长度

1.Python日期与时间工具

(1)原生Python日期时间工具

from datetime import datetime
from dateutil import parser

(2)时间类型数组:NumPy datetime64类型

日期与时间单位格式代码

代码 含义
Y
M
W
D
h
m
s
ms 毫秒
us 微秒
ns 纳秒
ps 皮秒
fs 飞秒
as 原秒

(3)Pandas日期时间工具

  • Pandas所有关于日期时间的处理方法全部都是通过TimeStamp对象实现的。


  • 可以直接进行NumPy类型的向量化运算。


2.Pandas时间序列:用时间作索引

(1)Pandas时间序列数据结构

时间戳:Timestamp类型
周期型:Period类型
时间增量(持续时间):Timedelta类型

  • 能够解析多种多种日期时间格式


  • 当用一个日期减去另一个日期时,返回的结果是TimedeltaIndex类型



(2)时间频率与偏移量

Pandas频率代码

代码 描述
D
W
M 月末
Q 季末
A 年末
H 小时
T 分钟
S
L 毫秒
U 微秒
N 纳秒
B 天(仅含工作日)
BM 月末(仅含工作日)
BQ 季末(仅含工作日)
BA 年末(仅含工作日)
BH 小时(工作时间)
MS 月初
BMS 月初(仅含工作日)
B- 仅含工作日
-S
  • 所有代码都对应有一个偏移量,可以在pandas.tseries.offsets里找到
from pandas.tseries.offsets import BDay

(3)重新取样和频率转换

数据读取:

  • 1.安装pandas-datareader
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ pandas-datareader
  • 2.读取数据
from pandas_datareader import data
tencent = data.get_data_yahoo('0700.hk', start='2000-11-01', end='2019-08-20')
  • 3.读取收盘价
tencent = tencent['Close']
  • 4.画图
%matplotlib inline
import matplotlib.pyplot as plt
tencent.plot()

①重新取样和频率转换

重新取样

resample():数据累计
asfreq():数据选择

tencent.plot(alpha=0.5, style='-')
# resample()方法是数据累计采样,结果为上一年的均值
tencent.resample('BA').mean().plot(style=':')
# asfreq()方法是数据选择采样,结果为上一年最后一个工作日的收盘价
tencent.asfreq('BA').plot(style='k:')

plt.legend(['input', 'resample', 'asfreq'], loc='upper left')
fig, ax = plt.subplots(2, sharex=True)
data = tencent.iloc[: 10]

data.asfreq('D').plot(ax=ax[0], marker='o')

data.asfreq('D', method='bfill').plot(ax=ax[1], style=['-o'])
data.asfreq('D', method='ffill').plot(ax=ax[1], style=['--o'])
ax[1].legend(['back-fill', 'forward-fill'])

②时间迁移

时间迁移

shift():迁移数据
tshift():迁移索引

fig, ax = plt.subplots(3, sharey=True)
fig.subplots_adjust(hspace=0.36)

# 重新按天采样,向后填充缺失值
tencent = tencent.asfreq('D', method='pad')

tencent.plot(ax=ax[0])
# 迁移数据
tencent.shift(900).plot(ax=ax[1])
# 迁移索引
tencent.tshift(900).plot(ax=ax[2])

# 设置图例与标签
local_max = pd.to_datetime('2007-11-05')
offset = pd.Timedelta(900, 'D')

ax[0].legend(['input'], loc=2)
ax[0].get_xticklabels()[4].set(weight='heavy', color='red')
ax[0].axvline(local_max, alpha=0.3, color='red')

ax[1].legend(['input'], loc=2)
ax[1].get_xticklabels()[4].set(weight='heavy', color='red')
ax[1].axvline(local_max + offset, alpha=0.3, color='red')

ax[2].legend(['input'], loc=2)
ax[2].get_xticklabels()[1].set(weight='heavy', color='red')
ax[2].axvline(local_max + offset, alpha=0.3, color='red')

③移动时间窗口

  • Series和DataFrame有一个rolling属性,可以实现计算移动统计值。
rolling = tencent.rolling(365, center=True)
data = pd.DataFrame({'input': tencent, 'one-year rolling_mean': rolling.mean(), 'one-year rolling_std': rolling.std()})
ax = data.plot(style=['-', '--', ':'])
ax.lines[0].set_alpha(0.3)

十三、高性能Pandas:eval()与query()

1.pandas.eval()实现高性能运算

  • pandas.eval()方法用字符串代数式实现了DataFrame的高性能运算。
  • pandas.eval()在执行时不需要为临时数组分配全部内存。

2.pandas.eval()支持的运算

(1)算术运算符

pd.eval()支持所有的算术运算符

result1 = -df1 * df2 / (df3 + df4) - df1
result2 = pd.eval("-df1 * df2 / (df3 + df4) - df1")
np.allclose(result1, result2)

(2)比较运算符

pd.eval()支持所有的比较运算符,包括链式代数式

result1 = (df1 < df2) & (df2 <= df3) & (df3 != df4)
result2 = pd.eval('df1 < df2 <= df3 != df4')
np.allclose(result1, result2)

(3)位运算符

pd.eval()支持&(与)、|(或)等运算符

result1 = (df1 < 0.5) & (df2 <= 0.5) & (df3 < df4)
result2 = pd.eval('(df1 < 0.5) & (df2 <= 0.5) & (df3 < df4)')
np.allclose(result1, result2)

(4)对象属性与索引

result1 = df2.T[0] + df3.iloc[1]
result2 = pd.eval('df2.T[0] + df3.iloc[1]')
np.allclose(result1, result2)

注意:目前pd.eval()尚不支持函数调用、条件语句、循环及更复杂的运算。如果需要进行这些运算,可以借助Numexpr来实现。

3.DataFrame.eval()实现列间运算

df = pd.DataFrame(np.random.rand(1000, 3), columns=['A', 'B', 'C'])
result1 = (df['A'] + df['B']) / (df['C'] - 1)
result2 = pd.eval("(df.A + df.B) / (df.C - 1)")
# 更简洁的方式
result3 = df.eval("(A + B) / (C - 1)")
np.allclose(result1, result2), np.allclose(result1, result3)
  • 1.新增列


  • 2.修改列


  • 3.DataFrame.eval()使用局部变量


4.DataFrame.query()方法

Cmean = df['C'].mean()
result1 = df[(df.A < Cmean) & (df.B < Cmean)]
result2 = df.query("A < @Cmean and B < @Cmean")
np.allclose(result1, result2)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容