数据分析——快递电商

一、任务目标

1、任务

总体目的——对账

本项目解决同时使用多个快递发货,部分隔离区域出现不同程度涨价等情形下,如何快速准确核对账单的问题。

1、在订单表中新增一列【运费差异核对】来表示订单运费实际有多少差异,结果为数值。

2、将整个核对过程包装为一个OrderCheck类,方便后续直接调用它进行数据核对。

二、数据形式

1、图像呈现

账单形式

邮寄费(不同公司)

2、文字描述

一个excel文件中有四个表,第一张是账单形式,后面是不同公司的计费方式

每个公司的信息不同(如送达地址的描述、包裹重量单位等),需要统一

三、分析步骤

1、导入数据

3.1.1存在问题

问题一:

由于原数据表中有空格,或最后有总计、数据源等不规则信息导致的,需要进行处理

问题二:

用describe()查看数值信息,发现只有邮资是纯数值,则需要对其他属性的数据进行数值转换

本数据源中,理应只有包裹重量和实际邮资是数值

但由于包裹重量的最后一行是单位(整个表最后的统计部分),不能被统计为数值

3.1.2解决方案

1、处理空行和空值

思路1:用loc定位删除空行

缺点:若新加入表,则行索引会改变,定位也就改变了

思路2:删除重复值

因为有三行空值,可先删除重复的空行

缺点:前面有数据的部分也许也会有重复值,容易导致数据缺失

思路3:统计每一行空值,判断需要删除的行

2、数据类型转换

3.1.3

语法扩展

2、数据处理

3.2.1计算运费

方法一:for循环算每一行

分析:根据地区、快递公司、重量计算运费

问题1:地区不统一

每个表的“地区”描述形式不一样

处理1:

1、读入所有表

2、统一各个表的名称

一张表:

reaname(,inplace=True)

多张表:

问题2:内容不统一

每个表省份的内容不一样

处理2:

问题3:单位不统一

每个表首重续重的写法不同,需要统一

处理3: 

问题4:时间是object型,而非数值型

不能直接用于时间的比较和计算,需要转换

处理4:

进一步分析

1、取出所需数据

 

2、计算每一行的运费

一个小问题,关于money的取值

 

 

 

 

方法二:apply()算某一行

暂未开发

3、数据分析

3.3.1将计算结果放入一个列表

3.3.2将所需数据加入表中

4、封装类

5、运行检查得结论 

1、调用

2、检查是否成功

3、数据异常

 

4、 核对后的数据

5、 存在差异的数据

四、总体代码

import pandas as pd 
import warnings
warnings.filterwarnings('ignore')
datas = pd.read_excel('./data_check_transport_fee.xlsx', sheet_name=None)
datas.keys()


# 各个表的名称处理
for k in datas.keys():
    datas[k].columns = ['省份' if '省' in i or '地' in i else i for i in datas[k].columns]


# 各个表的省份名称处理 广东省---->广东 
for k in datas.keys():
    datas[k]['省份'] = datas[k]['省份'].str[:2]


#把每张表拿出来
data = datas['账单明细']
st = datas['申通报价']
sf = datas['顺丰报价']
db = datas['德邦报价']


# 空行处理
data = data[data.isna().sum(axis=1)<5]
data.shap


# 筛选有缺失的数据
ind = data.isna().sum(axis=1)>0
data[ind ]


# 包裹在重量转为数值
data['包裹重量'] = data['包裹重量'].astype(float)


# 修改首重续重列名称
st.rename(columns={'首重(1KG)':'首重', '续重(/KG)':'续重'}, inplace=True)
sf.rename(columns={'首重(1kg)':'首重', '续重(1kg)':'续重'}, inplace=True)


# 修改时间格式
data['发货时间'] = pd.to_datetime(data['发货时间'] )


money_list = []
for province,area,ways,weight,times in data[['省份', '区市', '物流方式','包裹重量','发货时间']].values:
    weight = weight/1000 # 重量单位转换
    if ways=='申通快递':
        if weight<=1: # 首重
            money = st.loc[st['省份']==province, '首重']
        else: # 续重
            money = st.loc[st['省份']==province, '首重']+(weight-1)*st.loc[st['省份']==province, '续重']
        if times>pd.to_datetime('2020-03-31') and area=='武汉市':
            money += 0.5
    elif ways=='德邦快递':
        if weight<=1:
            money = db.loc[db['省份']==province, '1公斤']
        elif 1<weight<=2:
            money = db.loc[db['省份']==province, '2公斤']
        elif 2<weight<=3:
            money = db.loc[db['省份']==province, '3公斤']
        elif 3<weight<=4:
            money = db.loc[db['省份']==province, '4公斤']
        elif 4<weight<=5:
            money = db.loc[db['省份']==province, '5公斤']
        else: 
            money = db.loc[db['省份']==province, '5公斤'] + (weight-5)*db.loc[db['省份']==province, '5公斤以上续']
        
    elif ways=='顺丰寄付':
        if weight<=1: # 首重
            money = sf.loc[sf['省份']==province, '首重']
        else: # 续重
            money = sf.loc[sf['省份']==province, '首重']+(weight-1)*sf.loc[sf['省份']==province, '续重']
    else: # 顺丰到付
        money = pd.Series(0)
    try:
        money_list.append(money.values[0])
    except:
        money_list.append(-999)


#把数据加入表中
data['运费差异核对'] = money_list
data['差异'] = data['实际邮资'] - data['运费差异核对']


#定义类和函数
# 定义一OrderCheck, 返回异常数据、核对异常的数据、核对正常数据
class OrderCheck():
    def __init__(self, root):
        self.root = root
        self.data, self.st, self.sf, self.db = self.prepare_data()
        
    def prepare_data(self,):
        datas = pd.read_excel(self.root, sheet_name=None)
        ## 各个表的名称处理
        for k in datas.keys():
            datas[k].columns = ['省份' if '省' in i or '地' in i else i for i in datas[k].columns]
        ## 各个表的省份名称处理 广西壮族自治区-->广西 
        for k in datas.keys():
            datas[k]['省份'] = datas[k]['省份'].str[:2]
        data = datas['账单明细']
        st = datas['申通报价']
        sf = datas['顺丰报价']
        db = datas['德邦报价']
        ## 空行处理
        data = data[data.isna().sum(axis=1)<5]
        ## 包裹在重量转为数值
        data['包裹重量'] = data['包裹重量'].astype(float)
        ## 修改首重续重列名称
        st.rename(columns={'首重(1KG)':'首重', '续重(/KG)':'续重'}, inplace=True)
        sf.rename(columns={'首重(1kg)':'首重', '续重(1kg)':'续重'}, inplace=True)
        # 修改时间格式
        data['发货时间'] = pd.to_datetime(data['发货时间'] )
        return data,st,sf,db
    
    def get_bad_data(self): # 返回异常数据
        # 筛选有缺失的数据
        ind = self.data.isna().sum(axis=1)>0
        return self.data[ind]
        
    def check(self):
        data, st, sf, db = self.prepare_data()
        money_list = []
        for province,area,ways,weight,times in data[['省份', '区市', '物流方式','包裹重量','发货时间']].values:
            weight = weight/1000 # 重量单位转换
            if ways=='申通快递':
                if weight<=1: # 首重
                    money = st.loc[st['省份']==province, '首重']
                else: # 续重
                    money = st.loc[st['省份']==province, '首重']+(weight-1)*st.loc[st['省份']==province, '续重']
                if times>pd.to_datetime('2020-03-31') and area=='武汉市':
                    money += 0.5
            elif ways=='德邦快递':
                if weight<=1:
                    money = db.loc[db['省份']==province, '1公斤']
                elif 1<weight<=2:
                    money = db.loc[db['省份']==province, '2公斤']
                elif 2<weight<=3:
                    money = db.loc[db['省份']==province, '3公斤']
                elif 3<weight<=4:
                    money = db.loc[db['省份']==province, '4公斤']
                elif 4<weight<=5:
                    money = db.loc[db['省份']==province, '5公斤']
                else: 
                    money = db.loc[db['省份']==province, '5公斤'] + (weight-5)*db.loc[db['省份']==province, '5公斤以上续']

            elif ways=='顺丰寄付':
                if weight<=1: # 首重
                    money = sf.loc[sf['省份']==province, '首重']
                else: # 续重
                    money = sf.loc[sf['省份']==province, '首重']+(weight-1)*sf.loc[sf['省份']==province, '续重']
            else: # 顺丰到付
                money = pd.Series(0)
            try:
                money_list.append(money.values[0])
            except:
                money_list.append(-999)
        data['运费差异核对'] = money_list
        data['差异'] = data['实际邮资'] - data['运费差异核对']
        return data 



#调用一下
che = OrderCheck('./data_check_transport_fee.xlsx')

#检查路径和是否成功
che.root 
che.st

#查看异常数据
che.get_bad_data()

#查看核对数据
check_data = che.check()

#查看差异存在的数据
check_data[check_data['差异']==0]

五、总结

5.1难点总结

1、异常值处理

询问业务、手动填补、try

2、名称、内容、单位、数值类型的统一

3、重量计算

用定位实现,要注意取不到最后一行的需要+1

4、类的书写和函数定义

取值需要多尝试,要清楚的判断数值类型,输出类型,用value或多套data,或者分开取

5.2方案总结

5.2.1思维总结

1、对于订单、账单等含有多种数值、涉及计算的数据源,需要多次用info()查看数据类型,确保类型为纯数值,方便后续处理

2、拿到数据源后,要根据目标or要得到的分析结果,判断表中的有效信息数据为哪些,并取出来

3、找表之间的关系时,想到表连接,或内容匹配(如:河北省与河北,都有河北二字,就取相同值)

5.2.2方法总结

1、数值转换

2、空值处理

isna()

3、将数据加入列表再加入表

4、数值获取

········太多了都在上面了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/298741.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【书生·浦语大模型实战营02】《轻松玩转书生·浦语大模型趣味Demo》学习笔记

《轻松玩转书生浦语大模型趣味Demo》 1、InternLM-Chat-7B 智能对话&#xff1a;生成 300 字的小故事 本节中我们将使用InternLM-Chat-7B 模型部署一个智能对话 Demo。 1.1 环境准备 在InternStudio平台中选择 A100(1/4) 的配置&#xff0c;镜像选择 Cuda11.7-conda&#x…

idea中使用Lombok 失效,@Slf4j 找不到符号的解决办法

文章目录 一、前言二、问题排查和解决方案三、 其他解决方案3.1 另一种解决方案3.2 参考文章 一、前言 今天在一个多module工程中&#xff0c;新增了一个 springboot&#xff08;版本 2.2.4.RELEASE&#xff09; module&#xff0c;像往常一样&#xff0c;我引入了lombok依赖&…

电脑开启虚拟化如何查看自己的主机主板型号

问题描述 在使用virtualbox、vmware安装虚拟机的时候&#xff0c;需要本机电脑能够支持虚拟化。 但是不同厂家的主机&#xff08;主板&#xff09;幸好并不一致&#xff0c;所以需要先了解自己的电脑主板型号 操作方法 1、win r 键打开运行窗口&#xff0c;输入cmd并确定打开…

关于“Python”的核心知识点整理大全64

目录 20.2.15 确保项目的安全 settings.py 20.2.16 提交并推送修改 20.2.17 创建自定义错误页面 1. 创建自定义模板 500.html settings.py settings.py 注意 views.py 20.2.18 继续开发 往期快速传送门&#x1f446;&#xff08;在文章最后&#xff09;&#xff1a…

大数据Doris(五十一):Colocation Join介绍

文章目录 Colocation Join介绍 一、原理 二、使用方式 1、建表 2、删表

【Java EE初阶七】多线程案例(生产者消费者模型)

1. 阻塞队列 队列是先进先出的一种数据结构&#xff1b; 阻塞队列&#xff0c;是基于队列&#xff0c;做了一些扩展&#xff0c;适用于多线程编程中&#xff1b; 阻塞队列特点如下&#xff1a; 1、是线程安全的 2、具有阻塞的特性 2.1、当队列满了时&#xff0c;就不能往队列里…

MATLAB插值函数

一、MATLAB插值函数概览 1&#xff09;本节重点介绍的插值函数 MATLAB插值函数适用情况基础句式interp1 函数interp1 主要用于一维数据的插值interp1(x, y, x_interp, ‘linear’); 其中 x 和 y 是已知数据点&#xff0c;x_interp 是要插值的目标点。interp2 函数interp2 用于…

VS code的使用介绍

VS code的使用介绍 简介下载和安装常用的插件使用教程快捷键 集成Git未找到 Git。请安装 Git&#xff0c;或在 "git.path" 设置中配置。操作步骤打开文件夹初始化仓库文件版本控制状态提交文件到git打开git操作栏位 好用的插件ChineseDraw.io Integration实体关系 Gi…

SpringSecurity集成JWT实现后端认证授权保姆级教程-环境搭建篇

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a;知识浅谈 &#x1f525;网站…

C++ UTF-8与GBK字符的转换 —基于Linux 虚拟机 (iconv_open iconv)

1、UTF-8 和 GBK 的区别 GBK&#xff1a;通常简称 GB &#xff08;“国标”汉语拼音首字母&#xff09;&#xff0c;GBK 包含全部中文字符。 UTF-8 &#xff1a;是一种国际化的编码方式&#xff0c;包含了世界上大部分的语种文字&#xff08;简体中文字、繁体中文字、英文、…

Android 15即将到来,或将推出5大新功能特性

Android15 OneUI电池优化 三星最近完成了对其所有设备的稳定版 One UI 6.0 更新的推出&#xff0c;引起了用户的极大兴奋。据新出现的互联网统计数据显示&#xff0c;即将发布的基于 Android 15 的 One UI 7 将通过优化电池和功耗来重新定义用户体验&#xff0c;这是一项具有突…

[AutoSar]基础部分 RTE 04 数据类型的定义及使用

目录 关键词平台说明一、数据类型分类二、Adt三、Idt四、Base 数据类型五、units六、compu methods七、data constraint 关键词 嵌入式、C语言、autosar、Rte 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、数据…

FineBI实战(2):案例架构说明及数据准备

1 系统架构 基于MySQL搭建数据仓库基于Kettle进行数据处理帆软FineBI基于MySQL搭建的数据仓库进行数据分析 2 数据流程图 通过Kettle将MySQL业务系统数据库中&#xff0c;将数据抽取出来&#xff0c;然后装载到MySQL数据仓库中。编写SQL脚本&#xff0c;对MySQL数据仓库中的数…

时序预测 | Matlab实现EEMD-SSA-BiLSTM、EEMD-BiLSTM、SSA-BiLSTM、BiLSTM时序预测对比

时序预测 | Matlab实现EEMD-SSA-BiLSTM、EEMD-BiLSTM、SSA-BiLSTM、BiLSTM时间序列预测对比 目录 时序预测 | Matlab实现EEMD-SSA-BiLSTM、EEMD-BiLSTM、SSA-BiLSTM、BiLSTM时间序列预测对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现EEMD-SSA-BiLSTM、…

Java十种经典排序算法详解与应用

数组的排序 前言 排序概念 排序是将一组数据&#xff0c;依据指定的顺序进行排列的过程。 排序是算法中的一部分&#xff0c;也叫排序算法。算法处理数据&#xff0c;而数据的处理最好是要找到他们的规律&#xff0c;这个规律中有很大一部分就是要进行排序&#xff0c;所以需…

关于 LockWindowUpdate 的最终总结

经过前面两篇文章的”洗礼”&#xff0c;我想&#xff0c;你应该知道了在何种情况下应该使用 LockWindowUpdate。 但接下来我要告诉你的是为什么不能使用它&#xff0c;即使是用于它本身的预期目的。 让我们回到古老的旧时代&#xff0c;那个时候&#xff0c;LockWindowUpdate…

docker、docker-compose 离线安装、shell脚本一键安装、卸载

注&#xff1a;二进制包&#xff0c;与脚本在同级目录 docker 离线安装&#xff1a; 包下载&#xff1a;https://download.docker.com/linux/static/stable/x86_64/ docker_install.sh&#xff1a; #!/bin/bash# 指定 Docker 版本和文件名 DOCKER_VERSION"24.0.7" D…

【InternLM】书生-浦语大模型demo搭建服务接口部署本地映射

目录 前言一、InternLM大模型介绍1-1、大模型简介1-2、InternLM大模型简介1-2-1、InternLM-7B1-2-2、InternLM-20B 二、从0开始搭建InternLM-Chat-7B 智能对话 Demo2-0、环境搭建2-1、创建虚拟环境2-2、导入所需要的包2-3、模型下载2-4、代码克隆2-5、终端运行 三、服务器接口部…

真核微生物基因组质量评估工具EukCC的安装和详细使用方法

介绍&#xff1a; GitHub - EBI-Metagenomics/EukCC: Tool to estimate genome quality of microbial eukaryotes 安装&#xff1a; docker&#xff1a; docker pull microbiomeinformatics/eukcc 推荐conda 环境&#xff1a; conda install -c conda-forge -c bioconda …

Python+Torch+FasterCNN网络目标检测识别

程序示例精选 PythonTorchFasterCNN网络目标检测识别 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《PythonTorchFasterCNN网络目标检测识别》编写代码&#xff0c;代码整洁&#xff0c;规…