美文网首页数据蛙数据分析每周作业
关于apply函数和numpy.int64类型问题

关于apply函数和numpy.int64类型问题

作者: bf3780a4db09 | 来源:发表于2019-01-26 22:29 被阅读3次

    最近开始学pandas了,这两天一直在做练习,总结一下今天碰到的两个问题。
    第一个是apply函数
    问题是这样的:我需要把Mjob和Fjob这两个字段的值转换成首字母的形式,这两个字段都是字符串形式。
    写了一个函数如下

    str_function = lambda str:str.capitalize()
    

    打算用apply函数执行的时候碰到了问题

    df[['Mjob','Fjob']].apply(str_function)
    

    结果报错了:说是Series对象没有capitalize()这个方法


    image.png

    刚开始的时候,不太懂什么意思,只是觉得两个字段都是字符串,应该都可以用capitalize()这个方法。后来,看到这种方法可以运行成功

    df['Mjob'].apply(str_function)
    df['Fjob'].apply(str_function)
    

    结果为


    image.png
    image.png

    刚看到这个写法运行成功的时候,我更懵了,df[['Mjob','Fjob']]加上apply方法,可以按列执行相应的函数,每一列的类型也都是Series;df['Mjob']这种写法也是Series,为什么同样是Series结果却不一样呢?查看一下,传入apply之后,参数的类型

    def get_type(s):
        print(type(s))
    df['Mjob'].apply(get_type)
    

    结果是


    image.png
    df[['Mjob','Fjob']].apply(get_type)
    
    image.png
    由此可见,第一个Series对象传入apply的时候是一次传入每个值,是元素级别的操作;第二个数据框对象传入apply的时候是依次传入每一列,如果要对数据框进行元素级别的操作,可以用applymap方法
    df[['Mjob','Fjob']].applymap(str_function)
    

    结果为


    image.png

    applymap()是数据框的元素级别操作方法,map()是Series的元素级别操作方法。
    既然,apply传入的是列,那么我是不是在函数中加入一个遍历Series对象的语句就可以了呢?然后,我又做了一次试验

    num = pd.DataFrame({'A':[1,2,3,4,5,6],
                       'B':[7,8,9,10,11,12],
                       'C':list('abcdef')})
    def change_number(df):
        if type(df) is int:
            return df * 10
        else:
            return df
    

    我先尝试了applymap方法

    print(num.applymap(change_number))
    

    结果是正确的


    image.png

    再用apply,当然num数据肯定不会变,因为type(df)的结果为Series,返回的全是原值:

    num.apply(change_number)
    
    image.png

    然后,修改函数,加入遍历Series的语句:

    def change_number(df):
        for item in range(len(df)):
            if type(df[item]) is int:
                df[item] = df[item] * 10
        return df
    print(num.apply(change_number))
    

    结果


    image.png

    结果还是没变
    这里就遇到了今天的第二个问题,来查看一下遍历列的时候,每个元素的类型,以其中一个元素为例

    A = num['A']
    type(A[1])
    type(A[1]) is int
    type(2)
    

    返回

    image.png
    image.png
    image.png
    A[1]是数字2,A[1]的数据类型是numpy.int64,根据第二个返回结果,在Python中numpy.int64和int不是一个数据类型,但是单独的数字2类型是int,Series中的元素2类型就是numpy.int64。因此修改函数将判断语句中的int改为numpy.int64,结果就对了。
    def get_series_number(df):
        for item in range(len(df)):
            if type(df[item]) is np.int64:
                df[item] = df[item] * 10
        return df
    print(num.apply(get_series_number))
    
    image.png

    另:用int()就可以把numpy.int64类型改为int类型,即int(A[1])。

    相关文章

      网友评论

        本文标题:关于apply函数和numpy.int64类型问题

        本文链接:https://www.haomeiwen.com/subject/hcjwjqtx.html