• Python中map、apply、applymap的用法


    一、准备数据

    boolean=[True,False]
    gender=["男","女"]
    color=["white","black","yellow"]
    data=pd.DataFrame({
        "height":np.random.randint(150,190,100),
        "weight":np.random.randint(40,90,100),
        "smoker":[boolean[x] for x in np.random.randint(0,2,100)],
        "gender":[gender[x] for x in np.random.randint(0,2,100)],
        "age":np.random.randint(15,90,100),
        "color":[color[x] for x in np.random.randint(0,len(color),100) ]
        }
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    二、Series数据处理

    2.1map用法

    如果需要把数据集中gender列的男替换为1,女替换为0,怎么做呢?绝对不是用for循环实现,使用Series.map()可以很容易做到,最少仅需一行代码。

    # 1. map用法
    # 1
    data['gender'] = data['gender'].map({
        "男": 1,
        "女": 0
    })
    # 2
    def gender_map(x):
        gender = 1 if x == '男' else 0
        return gender
    data['gender'] = data['gender'].map(gender_map)
    print(data['gender'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述
    在这里插入图片描述
    不论是利用字典还是函数进行映射,map方法都是把对应的数据逐个当作参数传入到字典或函数中,得到映射后的值。

    2.2apply

    同时Series对象还有apply方法,apply方法的作用原理和map方法类似,区别在于apply能够传入功能更为复杂的函数。怎么理解呢?一起看看下面的例子。

    假设在数据统计的过程中,年龄age列有较大误差,需要对其进行调整(加上或减去一个值),由于这个加上或减去的值未知,故在定义函数时,需要加多一个参数bias,此时用map方法是操作不了的(传入map的函数只能接收一个参数),apply方法则可以解决这个问题。

    # 2. apply
    def apply_age(x, bias):
        return x + bias
    #以元组的方式传入额外的参数  可以看到age列都减了3
    data['age'] = data['age'].apply(apply_age, args=(-3,))
    print(data['age'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    可以看到age列都减了3,当然,这里只是简单举了个例子,当需要进行复杂处理时,更能体现apply的作用。

    总而言之,对于Series而言,map可以解决绝大多数的数据处理需求,但如果需要使用较为复杂的函数,则需要用到apply方法。

    3.DataFrame数据处理

    3.1apply

    对DataFrame而言,apply是非常重要的数据处理方法,它可以接收各种各样的函数(Python内置的或自定义的),处理方式很灵活,下面通过几个例子来看看apply的具体使用及其原理。

    在进行具体介绍之前,首先需要介绍一下DataFrame中axis的概念,在DataFrame对象的大多数方法中,都会有axis这个参数,它控制了你指定的操作是沿着0轴还是1轴进行。axis=0代表操作对列columns进行,axis=1代表操作对行row进行,如下图所示。
    在这里插入图片描述
    假设现在需要对data中的数值列分别进行取对数和求和的操作,这时可以用apply进行相应的操作,因为是对列进行操作,所以需要指定axis=0,使用下面的两行代码可以很轻松地解决我们的问题。

    # 沿着0轴求和
    data[["height","weight","age"]].apply(np.sum, axis=0)# 沿着0轴取对数
    data[["height","weight","age"]].apply(np.log, axis=0)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    当沿着轴0(axis=0)进行操作时,会将各列(columns)默认以Series的形式作为参数,传入到你指定的操作函数中,操作后合并并返回相应的结果。

    那如果在实际使用中需要按行进行操作(axis=1),那整个过程又是怎么实现的呢?

    在数据集中,有身高和体重的数据,所以根据这个,我们可以计算每个人的BMI指数(体检时常用的指标,衡量人体肥胖程度和是否健康的重要标准),计算公式是:体重指数BMI=体重/身高的平方(国际单位kg/㎡),因为需要对每个样本进行操作,这里使用axis=1的apply进行操作,代码如下:

    def BMI(series):
        weight = series["weight"]
        height = series["height"]/100
        BMI = weight/height**2
        return BMI
    ​
    data["BMI"] = data.apply(BMI,axis=1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    还是用图解的方式来看看这个过程到底是怎么实现的(以前5条数据为例)。
    在这里插入图片描述
    当apply设置了axis=1对行进行操作时,会默认将每一行数据以Series的形式(Series的索引为列名)传入指定函数,返回相应的结果。

    总结一下对DataFrame的apply操作:

    1. 当axis=0时,对每列columns执行指定函数;当axis=1时,对每行row执行指定函数。
    2. 无论axis=0还是axis=1,其传入指定函数的默认形式均为Series,可以通过设置raw=True传入numpy数组
    3. 对每个Series执行结果后,会将结果整合在一起返回(若想有返回值,定义函数时需要return相应的值)
    4. 当然,DataFrame的apply和Series的apply一样,也能接收更复杂的函数,如传入参数等,实现原理是一样的,具体用法详见官方文档。

    3.2. applymap

    applymap的用法比较简单,会对DataFrame中的每个单元格执行指定函数的操作,虽然用途不如apply广泛,但在某些场合下还是比较有用的,如下面这个例子。

    为了演示的方便,新生成一个DataFrame

    df = pd.DataFrame(
        {
            "A":np.random.randn(5),
            "B":np.random.randn(5),
            "C":np.random.randn(5),
            "D":np.random.randn(5),
            "E":np.random.randn(5),
        }
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    现在想将DataFrame中所有的值保留两位小数显示,使用applymap可以很快达到你想要的目的,代码和图解如下:

    df.applymap(lambda x:"%.2f" % x)
    
    • 1

    在这里插入图片描述

  • 相关阅读:
    python基于PHP+MySQL的超市管理系统
    Scala在大数据领域的崛起:当前趋势和未来前景
    视频流采集存储和展示技术调研
    go 学习01
    vue,uniapp生成二维码
    Spring Boot Validation提示信息国际化配置
    IBM X3650 M4服务器配置 并上线JavaWeb项目
    SpringCloud之gateway基本使用解读
    如何在Linux中使用read命令读取用户输入?——read命令实战
    RHCSA8.2
  • 原文地址:https://blog.csdn.net/weixin_43886282/article/details/127652436