• 3.Pandas高级函数应用


    3.1 函数应用

    3.1.1 apply

    apply()是一种可自定义的函数,可以对Series或DataFrame的行列进行操作并返回结果,可以用于复杂逻辑的实现,针对Series和DataFrame的应用有区别:Series作用每一个元素,不用设行列;DataFrame需要设置行列方向,并作用于其中一种。

    (1)Series

    df['score'].apply(lambda x: x-3 if x>90 else x)

    (2)DataFrame

    1. # 作用于列元素:aixs=0
    2. def col(x):
    3.   if x.name='score':
    4.     return x+5
    5.   else:
    6.     return x
    7.  
    8. df.apply(col, axis=0)
    9. # 作用于行元素:axis=1
    10. def row(x):
    11.   if x['subject']=='lakers':
    12.     a = 1
    13.   else:
    14.     a = 1.2
    15.   return x['score']*a
    16. df.apply(row, axis=1)

    (3)传入参数

    1. # args额外参数
    2. def score_bias(x, bias):
    3.   if x>90:
    4.     return x+bias
    5.   else:
    6.     return x
    7.  
    8. df['score'] = df['score'].apply(score_bias, args=(bias,))

    (4)传入关键字

    1. def subject_map(x, **kwargs):
    2.   return kwargs[x]
    3. df['subject_no'] = df['subject'].apply(subject_map, english=0, math=1)

    3.1.2 applymap

    只能作用在DataFrame上,操作对象是每个元素,即接收一个标量元素返回一个标量元素,点对点操作。

    1. def el_cook(x):
    2.   if isinstance(x, str):
    3.     return 's_'+x
    4.   else:
    5.     return str(x)
    6. df.apply(el_cook)

    3.1.3 map

    只能作用在Series上。

    (1)字典映射

    1. GENDER_ENCODING = {
    2.   "male": 0,
    3.   "femal": 1
    4. }
    5. df['gender_map'] = df['gender'].map(GENDER_ENCODING)

    (2)函数映射

    map相对于apply无法传参,但是效率高很多。

    1. # 普通函数
    2. df['score'],map(np.sqrt)
    3. df['student'].map(list)
    4. # 自定义函数
    5. df['score'].map(lambda x:x-3 if x>90 else x)

    3.1.4 transform

    • 对series和DataFrame都使用,DataFrame可选择处理的轴方向,默认是列方向。

    • 不支持有降维功能的函数,比如聚合函数min、mean、std。

    • 返回结果与自身形状相同,不改变原数据形状。

    1. ### 单个函数
    2. df.transform(np.exp).transform(lambda x: round(x,2))
    3. ### 多个函数
    4. # 列表形式
    5. df.transform([np.square, np.sqrt]).transform(lambda x: round(x,2))    # 平方、开平方根(产生多级索引,一级是列名,二级是函数名)
    6. # 字典形式
    7. df.transform({'C_0':np.square, 'C_2':[np.square, np.sqrt]}).transform(lambda x:round(x,2))          # 对指定列进行差异化的函数转换

    3.1.5 pipe

    不同于applymap元素级,apply/transform行列级应用,pipe是一个表级应用函数,也称管道函数。

    1. ### 单个函数
    2. df.pipe(np.exp).pipe(lambda x:round(x,2))
    3. ### 链式调用
    4. pi = df.pipe(np.square).\
    5.         pipe(np.multiply, 1.5).\
    6.         pipe(np.add, 8)
    7. ### 特殊传参方式
    8. def spcl(num, df):
    9.   return df.add(num)
    10. df.pipe((spcl, 'df'), 2)      # spcl指定函数,2指定参数

    3.2 表达式求值

    3.2.1 eval

    eval()可以通过字符串表达式的方式对series和DataFrame进行计算和解析等操作。

    eval()函数有两大优势:

    • 对数据较大的DataFrame对象操作更高效;

    • 对复杂的算术和布尔运算更快速,因为后端计算引擎默认是numexpr

    如果数据量较小则没必要用eval,一般当数据量较大超过10000行的时候才建议使用eval()函数进行加速。

    eval()支持以下算术操作:

    • 算术运算:除左移(<<)和右移(>>)运算符外的算术运算;

    • 比较操作:包括链式比较,例如,2

    • 布尔运算:例如,df

    • 列表和元组:如[1,2],(1,2);

    • 属性访问:如df.a;

    • 下标表达式:如df[0];

    • 变量评估:如pd.eval("df");

    • 数学函数:如sin,cos,exp等。

    eval()不允许使用Python语法:

    • 表达式

      • 数学函数以外的函数调用

      • is/is not操作

      • if表达式

      • lambda表达式

      • list/set/dict

      • literal的dict和set表达式

      • yield表达

      • 生成器表达式

      • 仅包含标量值的布尔表达式

    • 声明

      • for, while, if

    eval()在pandas中有两种函数形式。

    1. ##### 函数1 #####
    2. pandas.eval()
    3. ----------
    4. 返回:eval解析出来的格式,ndarray,scalar,pandas对象,或None

    参数:

    • expr:指定要被解析的字符串,不能包括任何python的声明 。

    • parser:指定解析方式,可以是pandas或python,默认为pandas。

    • engine:后端支持的计算引擎:

      • None:尝试使用numexpr引擎如果失效则切换到python引擎

      • numexpr:默认引擎(需要额外安装),可以大幅提高有复杂表达式数据的速度

      • python:可以像在python中使用eval执行操作一样

    • target:当expr表达式里有变量赋值时,需要指定变量所在的DataFrame对象。

    • inplace:如果指定了target,是否对target生效,True代表生效,False则返回target的复制。

    1. #### 函数2 #####
    2. dataframe.eval()
    3. ----------
    4. 返回:eval解析出来的格式,ndarray,scalar,pandas对象,或None

    dataframe.eval()是pandas.eval()的高级封装,可以专门对dataframe对象操作,无需指定target。

    参数:

    expr和inplace可单独设置,同上。其他参数可通过**kwargs关键字进行设置。

    (1)单列变量

    1. pd.eval("C_4 = (df.C_0>1) & (df.C_2 == 4)", target=df)
    2. df.eval("C_4 = (df.C_0>1) & (df.C_2 == 4)")

    0

    1

    4

    2

    2

    FALSE

    1

    4

    1

    1

    4

    FALSE

    2

    1

    4

    4

    4

    FALSE

    3

    2

    1

    4

    1

    TRUE

    4

    3

    2

    1

    2

    FALSE

    (2)多列变量

    1. df.eval(
    2.   """
    3.   C_4 = C_0 + C_1
    4.   C_5 = C_1 + C_2
    5.   C_6 = C_2 + C_3
    6.   """
    7. )

    0

    1

    4

    2

    2

    5

    6

    4

    1

    4

    1

    1

    4

    5

    2

    5

    2

    1

    4

    4

    4

    5

    8

    8

    3

    2

    1

    4

    1

    3

    5

    5

    4

    3

    2

    1

    2

    5

    3

    3

    (3)局部变量

    字符串表达式中可加入局部变量参与计算,通过@前缀标识完成。该前缀方法只能应用于dataframe.eval()函数,对于panda.eval()不生效。

    1. a = 5
    2. b = 2
    3. df.eval("C_4 = C_0 * @a + @b")

    0

    1

    4

    2

    2

    7

    1

    4

    1

    1

    4

    22

    2

    1

    4

    4

    4

    7

    3

    2

    1

    4

    1

    12

    4

    3

    2

    1

    2

    17

    (4)类型解析

    注意这里的eval()是python内置的方法,不是pandas提供的函数,无需调用。

    1. # 字符类型
    2. a = '[1,2,3]'
    3. >>> type(a)
    4. str
    5. # eval释放
    6. b = eval(a)            # 去掉'',并自动转换成里面数据该有的类型
    7. >>> type(b)
    8. list
  • 相关阅读:
    Python 支付宝红包二维码制作步骤分享
    python+windows画图工具--复现别人论文中的colormap 方法2
    springboot+nodejs+vue高校实验室设备管理系统
    第1章 人工智能的基础概念与应用导论
    ICPC2023深圳部分题解(A,D,E,F,G,K,L)
    音频学习笔记之音频采集
    html在线生成二维码(附源码)
    JAVA电商平台免费搭建 B2B2C商城系统 多用户商城系统 直播带货 新零售商城 o2o商城 电子商务 拼团商城 分销商城
    复杂环境下多移动机器人路径规划研究(Matlab代码实现)
    你把 《时间》 玩明白
  • 原文地址:https://blog.csdn.net/PyDarren/article/details/134487936