【Python】红旗超市线下缴电费用户数据分析及可视化(pandas+pyecharts)

场景分析:

一部分用户习惯在红旗超市线下进行缴电费,电力公司希望了解哪些用户喜欢到线下缴费,具体分布在哪里,才能有针对性地宣传掌上电力app引导用户体验更高效的线上缴费方式,提升用户满意度。

需求分析:

首先要拿到红旗超市线下缴费清单数据,对所有数据进行隐私化处理,数据预览如图所示:

ed9b9e5749df8a52644cc0ec0f632893.png

可以看出台区名称为本项目的核心字段,通过台区匹配到经纬度信息,然后利用经纬度信息进行线下缴费热力图展示。

同时可以提供分析报告,分缴费笔数和缴费金额两个维度来分析哪些台区线下缴费更多。

代码分析:

数据分析报告比较简单,可以直接读入数据,利用pandas来进行分析,最终将结果文件输出,我们先实现这部分的代码。

真实的缴费数据量级是十万级别,但台区会有很多重复,也就是家住在同一小区的,我们先看看台区大概有多少。

import pandas as pd
data = pd.read_excel(r"./成都红旗成都收费员收费记录/红旗连锁成都收费员-2022年1月交费数据.xlsx")
result=data["台区名称"].unique().tolist()
print(len(result))

结果量级变为了万级,也就是我们要匹配这几万户的经纬度。先不管经纬度,我们用已有信息从缴费笔数和缴费金额两个维度进行分析。

读取数据:

import pandas as pd
tb=pd.DataFrame(pd.read_excel(r"红旗连锁成都收费员-2022年1月交费数据.xlsx"))

对数据进行分组,求各台区收费总金额和缴费次数:

gp=tb.groupby(["区县","台区名称"])


d0=gp.sum().loc[:,["收费金额"]]


d1=gp.size()


d=pd.concat([d0,d1],axis=1)


d.columns=["总金额","缴费次数"]

对数据分别按总金额和缴费次数进行排序输出:

d_1=d.sort_values(by="总金额",ascending=False)


d_1.to_excel("统计信息_金额.xlsx")


d_2=d.sort_values(by="缴费次数",ascending=False)


d_2.to_excel("统计信息_缴费次数.xlsx")

此时我们就获得了一个简易的分析报告:

(统计信息_金额.xlsx)

区县台区名称总金额缴费次数
城西供电中心电子科大清水河台区7006
国网成都市温江供电公司四川电力职业技术学院台区6001
城东供电中心四川师范大学台区6002
四川大学台区5004
城西供电中心西南交通大学台区3003
国网成都市高新供电公司西南民族大学公变2002
国网都江堰市供电公司四川工商职业技术学院1001
城西供电中心西华大学台区1001


(统计信息_缴费次数.xlsx)

区县台区名称总金额缴费次数
城西供电中心电子科大清水河台区7006
城东供电中心四川大学台区5004
城西供电中心西南交通大学台区3003
国网成都市高新供电公司西南民族大学公变2002
城东供电中心四川师范大学台区6002
国网成都市温江供电公司四川电力职业技术学院台区6001
国网都江堰市供电公司四川工商职业技术学院1001
城西供电中心西华大学台区1001

分析报告显示:需要重点去宣传的小区是电子科大、四川大学、西南交大,因为他们线下缴费用户多,还有四川电力职业技术学院和四川师范大学,虽然用户不多,但是他们交的电费多。

表格看起来始终不够直观,那么可否进行热力图显示,当然可以,下面我们利用pyecharts进行热力图展示。

要进行热力图展示,此时我们还缺了一项数据,那就是台区的经纬度,正常情况下我们从数据中台中获取所有台区的经纬度信息进行匹配,由于台区经纬度信息同样属于保密数据,获取需要审批,此项目我们从另外一个渠道获取经纬度信息,那就是百度地图开放平台。

https://lbsyun.baidu.com/

ede1df31f05b972f4badff698ea99914.png

导入本项目需要的包:

from urllib.request import quote
import requests
import pandas as pd
import numpy as np
import json
pd.set_option('display.max_columns',None)

先写一个能够将中文字符串转化为经纬度的函数:

def getlnglat(address):
    url = 'http://api.map.baidu.com/geocoding/v3/'
    output = 'json'
    ak = '在百度地图开放平台申请的ak'
    address = quote(address) # 由于本文地址变量为中文,为防止乱码,先用quote进行编码
    uri = url + '?' + 'address=' + address  + '&output=' + output + '&ak=' + ak  +'&callback=showLocation%20'+'//GET%E8%AF%B7%E6%B1%82'
    res=requests.get(uri).text
    temp = json.loads(res)  # 将字符串转化为json
    lat = temp['result']['location']['lat']
    lng = temp['result']['location']['lng']
    return lng,lat   # 纬度 latitude,经度 longitude

再写一个能够从区县字符串中扣出对我们定位有用信息的函数:

def renew_quxian(x):
    if "供电中心" in x:
        return x.split("供")[0]
    if "供电公司" in x:
        temp = x.split("网")[1]
        if "成都市" in temp:
           temp1 = temp.split("供")[0]
           return temp1.split("市")[1]
        else:
            return temp.split("供")[0]

读入数据,利用所写的 renew_quxian函数构造一个新的字段——中文地址:

data["中文地址"]="成都市"+data["区县"].apply(renew_quxian)+data["台区名称"]

如果不构造这个中文地址字段,直接用台区名称,那么很有可能就定位到北上广深的同名小区去了,所以尽量利用成都市和区县信息替百度缩小搜索范围,当然也是为了提升我们定位的精确度。

假如有几十万的台区数据,里面又有重复的台区信息,总不能调用百度api几十万次吧,没有那么多额度,就算是认证用户,一天也只能查30w次。

aa1c087fdac4e2ce8fca0244a3b635a5.png

根据台区信息进行去重操作:

data_unique = data.iloc[data.groupby(['台区名称']).apply(
   lambda x: x['用户编号'].idxmax())]

去重后新增经纬度字段:

data_unique["经纬度"]=data_unique["中文地址"].apply(getlnglat)
r=data_unique.loc[:,["台区名称","经纬度"]]

根据台区名称和经纬度组成的键值对来构建city_coordinates.json文件:

for i in r.iterrows():
    k=i[1]['台区名称']
    v=i[1]['经纬度']
    mp[k]=v


f=open(r"city_coordinates.json", 'r',encoding='utf-8')
fs=str(f.read())
f.close()


old=json.loads(fs)  #json转obj
old.update(mp)      #把从excel里读到的更新进去
f=open(r"city_coordinates.json",'w',encoding='utf-8')
json.dump(old,f,ensure_ascii=False)
f.close()

city_coordinates.json结构如下图所示:

{"四川大学台区": [104.08399190311378, 30.63014203788181], "电子科大清水河台区": [103.93740389474014, 30.756035188715344], "西南交通大学台区": [103.99321381946406, 30.77039889704779], "四川师范大学台区": [104.12869113613753, 30.619258186581966], "西华大学台区": [104.07428849682555, 30.640677198288525], "四川电力职业技术学院台区": [103.84530242741315, 30.726613592027057], "西南民族大学公变": [104.02072415621548, 30.626048550861352], "四川工商职业技术学院": [103.70236701907363, 30.918967871107483]}

将city_coordinates.json文件替换至C:\ProgramData\Anaconda3\Lib\site-packages\pyecharts\datasets的原文件处,为在地图上显示做准备。

为了显示热力图要计算每个台区出现的次数,其实前面已经统计出来了,这里我们展示另外一种算法:

def getlistnum(li):
    set1 = set(li)
    dict1 = {}
    for item in set1:
        dict1.update({item:li.count(item)})
    return dict1


total = {}
total = getlistnum(data["台区名称"].tolist())

由于热力图展示的时候取值可以从0到100,100最红,0基本看不到,所以我们将最小值映射到50,最大值映射到100,我们在打绩效的时候其实也是这一套操作:

def fun(li):
    zhi=[]
    for i in li:
        scale = (i - min(li)) / (max(li) - min(li))
        zhi.append(50 + 50 * scale)
    return zhi

最后一步就是利用pyecharts画热力图:

from pyecharts.charts import BMap
from pyecharts import options as opts


def heatmap_heatmap() -> BMap:
    c = (
        BMap()
            .add_schema(baidu_ak="在百度地图开放平台申请的ak", center=[104.07231,30.663467])
            .add(
            "",
            [list(z) for z in zip(total.keys(), fun(total.values()))],
            type_="heatmap",
            label_opts=opts.LabelOpts(formatter="{b}"),
        )
            .set_global_opts(
            title_opts=opts.TitleOpts(title="",title_textstyle_opts = (opts.TextStyleOpts(color='red', font_size=50))),
            legend_opts=opts.LegendOpts(
                pos_left='80%',
                pos_top='20',
                textstyle_opts=opts.TextStyleOpts(color='black', font_size=30),
            ),
            tooltip_opts=opts.TooltipOpts(
                textstyle_opts=opts.TextStyleOpts(font_size=30),
                # background_color='green',
                border_color='black',
                border_width=3),
            visualmap_opts=opts.VisualMapOpts()
        )
            .render("红旗地图.html")
    )
    return c
heatmap_heatmap()

画出的热力图是一个html文件,可以全方位展示线下红旗缴电费用户的状况:

3a3a2cf930d1c65d32f55fa44a45d10d.png

2017ac15662712bdf8ad6652904e8622.png

由于数据是我伪造的,这里的效果其实是展示的成都市高校的情况,将数据换成真实业务数据,就可以得到我们想要的结果。

总结分析:

电量电费管理子系统是整个用电MIS系统的核心,它的主要功能是实现按月结算电费的直供用户和趸售用户的抄表、核算、及分析工作。 由于电力用户的复杂性,结算方式多种多样,另外还存在用电量的套扣情况,因此必须全面考虑,细致规划,才能提供完整、灵活的解决方案。 在用电管理信息系统中,我们引入‘抄表卡片’的概念。每个计量设备对应与一个卡片,变电站、高压计量箱、用户电表等,一表一卡,一一对应。抄表卡片具有多种性质,以便于计算、组织、管理。一个抄表卡片可以包含多个其他的抄表卡片,也可以同时属于别的抄表卡片。抄表卡片设有所属使用单位(也可以没有单位,例如总表),计费类别,电价类别,电量,线损,变压器及线路信息等。 通过‘抄表卡片’,可以线路及变压器组织起来,也可以体现用户之间的关系。利用抄表卡片,可以实现复杂而灵活的电费计算,可以非常容易的解决诸如电量套扣等难题。例如,如果某一抄表卡片的所属单位和其所属的上一级抄表卡片的所属单位不同,则该抄表卡片的电量电费将不属于其上一级抄表卡片所属的单位。 另外通过在抄表卡片中引入电量、计费类别和电价类别等属性,可以将电量、电费的计算和电价分开,便于实现复杂的电费计算,便于实现线损分摊,通过电价类别维护界面,可以实现灵活自如的电量电费管理
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值