数据分析——快递电商

一、任务目标

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.5elif 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 = rootself.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,dbdef get_bad_data(self): # 返回异常数据# 筛选有缺失的数据ind = self.data.isna().sum(axis=1)>0return 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.5elif 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_listdata['差异'] = 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、数值获取

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【无标题】关于异常处理容易犯的错

一般项目是方法打上 try…catch…捕获所有异常记录日志&#xff0c;有些会使用 AOP 来进行类似的“统一异常处理”。 其实&#xff0c;这种处理异常的方式非常不可取。那么今天&#xff0c;我就和你分享下不可取的原因、与异常处理相关的坑和最佳实践。 捕获和处理异常容易犯…

Feature Fusion for Online Mutual KD

paper&#xff1a;Feature Fusion for Online Mutual Knowledge Distillation official implementation&#xff1a;https://github.com/Jangho-Kim/FFL-pytorch 本文的创新点 本文提出了一个名为特征融合学习&#xff08;Feature Fusion Learning, FFL&#xff09;的框架&…

行走在深度学习的幻觉中:问题缘由与解决方案

如何解决大模型的「幻觉」问题&#xff1f; 我们在使用深度学习大模型如LLM&#xff08;Large Language Models&#xff09;时&#xff0c;可能会遇到一种被称为“幻觉”的现象。没错&#xff0c;它并不是人脑中的错觉&#xff0c;而是模型对特定模式的过度依赖&#xff0c;这…

Linux---gcc编译

目录 前言 一、gcc编译 二、程序的编译过程 三、gcc查看编译过程 1.预处理阶段 2.编译 3.汇编 4.链接 动静态库链接的内容 动静态库链接的优缺点 5.总结记忆 前言 在前面我们学会使用vim对文件进行编辑&#xff0c;如果是C或者C程序&#xff0c;我们编辑好了内容…

【DDR】基于Verilog的DDR控制器的简单实现(一)——初始化

在FPGA中&#xff0c;大规模数据的存储常常会用到DDR。为了方便用户使用&#xff0c;Xilinx提供了DDR MIG IP核&#xff0c;用户能够通过AXI接口进行DDR的读写访问&#xff0c;然而MIG内部自动实现了许多环节&#xff0c;不利于用户深入理解DDR的底层逻辑。 本文以美光(Micro…

【算法刷题】Day28

文章目录 1. 买卖股票的最佳时机 III题干&#xff1a;算法原理&#xff1a;1. 状态表示&#xff1a;2. 状态转移方程3. 初始化4. 填表顺序5. 返回值 代码&#xff1a; 2. Z 字形变换题干&#xff1a;算法原理&#xff1a;1. 模拟2. 找规律 代码&#xff1a; 1. 买卖股票的最佳时…

重学Java 4 进制转换和位运算

天赋不好好使用的话&#xff0c;可是会被收回的哦 ——24.1.13 一、进制转换 1.常用的进制 2.十进制和二进制之间的转换 1.十进制转二进制 辗转相除法——循环除以2&#xff0c;取余数&#xff0c;除到商为0为止&#xff0c;除完后&#xff0c;由下往上&#xff0c;得出换算后…

JVM基础(7)——ParNew垃圾回收器

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

Kafka(四)Broker

目录 1 配置Broker1.1 Broker的配置broker.id0listererszookeeper.connectlog.dirslog.dir/tmp/kafka-logsnum.recovery.threads.per.data.dir1auto.create.topics.enabletrueauto.leader.rebalance.enabletrue, leader.imbalance.check.interval.seconds300, leader.imbalance…

Redis之集群方案比较

哨兵模式 在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态&#xff0c;如果master节点异常&#xff0c;则会做主从切换&#xff0c;将某一台slave作为master&#xff0c;哨兵的配置略微复杂&#xff0c;并且性能和高可用性等各方面表现一般&a…

Node.js和npm

目录 01_Node.js01.什么是 Node.js目标讲解小结 02.fs模块-读写文件目标讲解小结 03.path模块-路径处理目标讲解小结 04.案例-压缩前端html目标讲解小结 05.认识URL中的端口号目标讲解小结 06.http模块-创建Web服务目标讲解小结 07.案例-浏览时钟目标讲解小结 02_Node.js模块化…

【LabVIEW FPGA入门】使用CompactRIO进行SPI和I2C通信

NI提供了 SPI and I2C Driver API&#xff1a;下载SPI and I2C Driver API - NI 该API使用FPGA数字I / O线与SPI或I2C设备进行通信。 选择数字硬件时&#xff0c;要考虑三个选项&#xff1a; NI Single-Board RIO硬件可同时使用SPI和I2C驱动程序。NI 9401 C系列模块与SPI驱动程…

LINUX网络

一、网络配置命令 1.1 ifconfig 命令功能ifconfig默认显示活动的显卡ifconfig -a显示所有的网卡ifconfig 网卡名称只显示前面的网卡信息ifconfig 网卡 down/ifdown 网卡关闭网卡ifconfig 网卡 up/ifup 网卡开启网卡ifconfig ens33:0 IP地址/子网掩码设置虚拟网卡 TYPEEthernet…

如何使用创建时间给文件重命名,简单的批量操作教程

在处理大量文件时&#xff0c;有时要按照规则对文件重命名&#xff0c;根据文件的创建时间来重命名。那如何批量操作呢&#xff1f;现在一起来看云炫文件管理器如何用文件的创建时间来批量重命名。 按创建时间重命名文件的前后对比图。 用创建时间批量给文件重命名的步骤&…

P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布————C++

目录 [NOIP2014 提高组] 生活大爆炸版石头剪刀布题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示 解题思路Code调用函数的Code&#xff08;看起来简洁一点&#xff09;运行结果 [NOIP2014 提高组] 生活大爆炸版石头剪刀布 …

人工智能_机器学习092_使用三维瑞士卷数据_利用分层聚类算法进行瑞士卷数据三维聚类---人工智能工作笔记0132

然后我们使用分层聚类算法来对我们导入的瑞士卷数据进行聚类 agg =AgglomerativeClustering(n_clusters = 6,linkage = ward) 可以看到这里我们使用的,聚类距离计算用的是,ward这种,最小化簇内方差的形式,l进行聚类对吧 可以看到这个linkage参数有好几个选择对吧,是之前我们讲过…

【Go】excelize库实现excel导入导出封装(三),基于excel模板导出excel

前言 大家好&#xff0c;这里是符华~ 关于excelize库实现excel导入导出封装&#xff0c;我已经写了两篇了&#xff0c;我想要的功能基本已经实现了&#xff0c;现在还差一个模板导出&#xff0c;这篇文章就来讲讲如何实现用模板导出excel。 前两篇&#xff1a; 【Go】excel…

Redis原理篇(Dict的收缩扩容机制和渐进式rehash)

Dict&#xff08;即字典&#xff09; Redis是一种键值型数据库&#xff0c;其中键与值的映射关系就是Dict实现的。 Dict通过三部分组成&#xff1a;哈希表&#xff08;DictHashTable&#xff09;&#xff0c;哈希节点(DictEntry)&#xff0c;字典&#xff08;Dict&#xff09…

JAVA静态引擎企业网站源码带文档

JAVA静态引擎企业网站源码带文档 系统介绍&#xff1a; 1.网站后台采用主流的 SSM 框架 jsp JSTL&#xff0c;网站前台采用freemaker静态化模版引擎生成html5 2.因为是生成的html&#xff0c;无需重复读取数据库&#xff0c;所以访问速度快&#xff0c;轻便&#xff0c;对服务器…

group by 查询慢的话,如何优化?

1、说明 根据一定的规则&#xff0c;进行分组。 group by可能会慢在哪里&#xff1f;因为它既用到临时表&#xff0c;又默认用到排序。有时候还可能用到磁盘临时表。 如果执行过程中&#xff0c;会发现内存临时表大小到达了上限&#xff08;控制这个上限的参数就是tmp_table…