Python每日一记193>>>AttributeError: 'DataFrame' object has no attribute 'map'

昨天在运行一段程序的时候,遇到了AttributeError: ‘DataFrame’ object has no attribute 'map’错误,但是很奇怪,明明之前也是类似的代码,不知道这次为什么出错了。
先看一下错误
在这里插入图片描述
发现错误发生的代码在以下这一句:

data_ks.loc[:, '区域段'] = data_ks.loc[:,'区域'].map(region_rule)

但是怎么想也觉得不对,因为明明data_ks.loc[:,‘区域’]就是选中的一列啊,不应该是DataFrame啊,于是再往上追溯:

gr_info=pd.concat([gr_kb,gr_age,gr_region,gr_region],axis=1,join='outer')

注意gr_region合并了两次,是我写错了,就导致有两个区域列,于是我们虽然是data_ks.loc[:,‘区域’],但是因为有两列区域列,就导致选出的是两列,也就是一个DataFrame,所以才报错,修改一下:

gr_info=pd.concat([gr_kb,gr_age,gr_region,gr_male],axis=1,join='outer')

这样就不会报错了。
总结一下,AttributeError: ‘DataFrame’ object has no attribute ‘map’错误,我们应该关注的点在于’DataFrame’ object和map,首先去检查是否是’DataFrame’ object,其次再去检查有没有map的属性,这样就能解决问题了。
网上有这个错误的其他解决方案,比如更新pandas等,但是感觉没有聚焦到问题本身,也就是应该专注于’DataFrame’ object,看看你进行操作的对象是否是’DataFrame’ object,再者才是应该关注’DataFrame’ object是否有map属性方法。

最后给上全部代码:

import numpy as np
import pandas as pd
import xlwings as xw
from pandas.api.types import CategoricalDtype  # 弥补astype的不足
# data_2015=pd.read_excel('E:\\ywj严文杰备份\\带时间消费明细-持续更新\\15年消费明细.xlsx')
# data_2016=pd.read_excel('E:\\ywj严文杰备份\\带时间消费明细-持续更新\\16年消费明细.xlsx')
# data_2017=pd.read_excel('E:\\ywj严文杰备份\\带时间消费明细-持续更新\\17年消费明细.xlsx')
data_2018=pd.read_excel('E:\\ywj严文杰备份\\带时间消费明细-持续更新\\18年消费明细.xlsx')
data_2019=pd.read_excel('E:\\ywj严文杰备份\\带时间消费明细-持续更新\\19年-1130.xlsx')
data=pd.concat([data_2018,data_2019],axis=0)

# 获取最终卡别,最终年龄,最终区域,最终性别
def get_info(d1):
    data1=d1
    # 卡别
    data_kb = data1.dropna(subset=['卡别'])
    # data_kb = data1
    gr_kb = data_kb[['卡号', '交易时间', '卡别']].groupby(by=['卡号']).apply(lambda x: x.sort_values(by='交易时间').iloc[-1, 2])
    gr_kb = pd.DataFrame(gr_kb)
    gr_kb.index.name = '索引'
    # gr_kb['卡号'] = gr_kb.index.tolist()
    gr_kb.columns = ['卡别']

    # 年龄
    data_age=data1.dropna(subset=['年龄'])
    # data_age=data1
    gr_age = data_age[['卡号', '交易时间', '年龄']].groupby(by=['卡号']).apply(lambda x: x.sort_values(by='交易时间').iloc[-1, 2])
    gr_age = pd.DataFrame(gr_age)
    gr_age.index.name = '索引'
    # gr_age['卡号'] =  gr_age.index.tolist()
    gr_age.columns = ['年龄']

    # 区域
    data_region=data1.dropna(subset=['区域'])
    gr_region = data_region[['卡号', '交易时间', '区域']].groupby(by=['卡号']).apply(lambda x: x.sort_values(by='交易时间').iloc[-1, 2])
    gr_region = pd.DataFrame(gr_region)
    gr_region.index.name = '索引'
    # gr_region['卡号'] =  gr_region.index.tolist()
    gr_region.columns = ['区域']

    # 性别
    # 男女编码
    data_male=data1.dropna(subset=['性别'])
    rule = {0: '男', 1: '女'}  # 创建字典
    data_male.loc[:,'性别'] = data_male.loc[:,'性别'].map(rule)  # 叫做映射
    gr_male = data_male[['卡号', '交易时间', '性别']].groupby(by=['卡号']).apply(lambda x: x.sort_values(by='交易时间').iloc[-1, 2])
    gr_male = pd.DataFrame(gr_male)
    gr_male.index.name = '索引'
    # gr_male['卡号'] =  gr_male.index.tolist()
    gr_male.columns = ['性别']

    # 合并
    gr_info=pd.concat([gr_kb,gr_age,gr_region,gr_male],axis=1,join='outer')
    gr_info['卡号']=gr_info.index.tolist()
    return gr_info

# 年龄编码,和卡别合并
def get_mingxi(d1,start,end,name):
    data1=d1
    data1['日期'] = pd.to_datetime(list(map(lambda x: x.date(), data1.loc[:, '交易时间'])))  # 转化为按天计算的日期
    data2 = data1.loc[(data1['日期'] >= pd.to_datetime(start)) & (data1['日期'] <= pd.to_datetime(end))]

    # 循环课室
    ks1 = data_2019.loc[~data_2019['课室'].isin(['人力资源部','超级市场课', '贩卖促进部', '店长办公室']), '课室'].drop_duplicates()
    for ks in ks1:
        data_ks = data2.loc[data2['课室'] == ks]
        data_info=get_info(data_ks)
        # 多对一merge
        data_ks=pd.merge(data_ks.loc[:,['卡号','交易时间','日期','专柜','部类','课室','销售金额']],data_info,how='left',on='卡号')
        data_ks['销售金额-求客单'] = data_ks['销售金额']
        # 年龄段编码
        if start[0:3] == '2018':
            data_ks['年龄'] = data_ks['年龄'] - 1
        # 开始编码分类等
        # 空的不会出错也不会编码,还是空,最后在填充即可
        # 直接编码替换
        data_ks['年龄段'] = pd.cut(data_ks['年龄'], [0, 20, 25, 30, 35, 40, 50, float('inf')],
                                 labels=['<=20岁', '21-25岁', '26-30岁', '31-35岁', '36-40岁', '41-50岁', '>50岁'])

        # 区域分类,有点多
        key1 = ['金牛区', '锦江区', '青羊区', '武侯区', '成华区', '龙泉驿区', '天府新区', '高新区', '双流区', '温江区', '郫都区', '新都区',
                '青白江区', '崇州市', '邛崃市', '大邑县', '新津县', '浦江县', '彭州市', '都江堰市', '金堂县',
                '巴中市', '遂宁市', '眉山市', '绵阳市', '乐山市', '泸州市', '自贡市', '资阳市', '雅安市', '甘孜阿垻', '德阳市', '广元市', '达州市', '南充市',
                '凉山彝族自治州', '内江市', '广安市', '宜宾市', '攀枝花市', '广汉市',
                '重庆',
                '其他']
        value1 = ['金牛区', '锦江区', '青羊区', '武侯区', '成华区', '龙泉驿区', '天府新区', '高新区', '双流区', '温江区', '郫都区', '新都区',
                  '成都郊县', '成都郊县', '成都郊县', '成都郊县', '成都郊县', '成都郊县', '成都郊县', '成都郊县', '成都郊县',
                  '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市',
                  '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市', '省内其他市',
                  '重庆',
                  '其他']
        region_rule = {key: value for key, value in zip(key1, value1)}  # 创建字典,注意zip的使用
        data_ks.loc[:, '区域段'] = data_ks.loc[:,'区域'].map(region_rule)



        # 卡别自定义排序
        data_ks['卡别'] =  data_ks['卡别'] .astype( CategoricalDtype(categories=['微会员', '金卡', '红宝石卡', '钻石卡'], ordered=True))

        # 年龄段自定义排序
        data_ks['年龄段'] = data_ks['年龄段'].astype(CategoricalDtype(categories=['<=20岁', '21-25岁', '26-30岁', '31-35岁', '36-40岁', '41-50岁', '>50岁'], ordered=True))

        # 区域段自定义排序
        data_ks['区域段'] = data_ks['区域段'].astype(CategoricalDtype(
            categories=['金牛区', '锦江区', '青羊区', '武侯区', '成华区', '龙泉驿区', '天府新区', '高新区', '双流区', '温江区', '郫都区', '新都区',
                        '成都郊县', '省内其他市', '重庆', '其他'], ordered=True))

        # 性别自定义排序
        data_ks['性别'] = data_ks['性别'] .astype(CategoricalDtype(categories=['男', '女'], ordered=True))

        #卡别分组
        data_ks_gr_kb=data_ks.groupby(by=['部类','专柜','卡别']).agg({'卡号':lambda x:len(set(x)),'销售金额':np.sum,'销售金额-求客单': np.mean})
        data_ks_gr_kb.index.name='卡别维度'
        data_ks_gr_kb.columns=['客数','销售金额','客单']

        # 年龄分组
        data_ks_gr_age = data_ks.dropna(subset=['年龄段']).groupby(by=['部类', '专柜', '年龄段']).agg({'卡号': lambda x: len(set(x)), '销售金额': np.sum, '销售金额-求客单': np.mean})
        data_ks_gr_age.index.name = '年龄维度'
        data_ks_gr_age.columns = ['客数', '销售金额', '客单']

        # 区域分组
        data_ks_gr_region = data_ks.dropna(subset=['区域段']).groupby(by=['部类', '专柜', '区域段']).agg(
            {'卡号': lambda x: len(set(x)), '销售金额': np.sum, '销售金额-求客单': np.mean})
        data_ks_gr_region.index.name = '区域维度'
        data_ks_gr_region.columns = ['客数', '销售金额', '客单']

        # 性别分组
        data_ks_gr_male = data_ks.dropna(subset=['性别']).groupby(by=['部类', '专柜', '性别']).agg(
            {'卡号': lambda x: len(set(x)), '销售金额': np.sum, '销售金额-求客单': np.mean})
        data_ks_gr_male.index.name = '性别维度'
        data_ks_gr_male.columns = ['客数', '销售金额', '客单']

        # 保存excel
        writer= pd.ExcelWriter(r'C:\Users\02180085\Desktop\python品牌细化分析\{}-2019年{}品牌细化分析.xlsx'.format(ks,name))
        data_ks_gr_kb.to_excel(writer,sheet_name='卡别维度')
        data_ks_gr_age.to_excel(writer, sheet_name='年龄维度')
        data_ks_gr_region.to_excel(writer, sheet_name='区域维度')
        data_ks_gr_male.to_excel(writer, sheet_name='性别维度')
        writer.save()
        writer.close()

get_mingxi(data, '2019-11-1', '2019-11-30','11月')
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值