您的位置:首页 > 编程语言 > Python开发

Excel与VBA对比Python与pandas数据分析方法总结

2019-03-30 23:00 615 查看

Excel和VBA对比Python和pandas数据方法总结

本内容以网上获取某电商公司的一段销售数据进行分析

Excel和VBA篇
首先用Excel打开表格,格式如下,总共一万多行,记录的是月销售记录,所有销售记录个表格格式都是一致的,因此,用VBA可以大大简化流程,减少复制和粘贴还有计算工作。

接下来打开VBA编辑器

Sub 调整类型()

Dim irow, a, sht, sht1, sht2, sht3
Dim arr()           '定义需要的变量和数组
Set sht = Application.ActiveSheet   '将当前活动的表格赋给变量sht
With sht     '对当前的表格进行操作
If .Range("b2") = "" Then        '处理1-6行表头,判断b2单元格是否为空
If .Range("n8") = "shipping credits" Then '如果n8单元格是某个值
Rows("1:7").Select     '选中1到7行,并将其删除
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp   '后面的列左移
Else          '如果n8单元格不是某个值
Rows("1:6").Select    '选中1到6行,并将其删除
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
End If
End If   'if函数的逻辑判断,在VBA比在Excel表格里面输入函数,来的更加灵活,更好理解

If .Range("n1") = "shipping credits" Then   '判断n1单元格是否为某个值
.Columns("Q:R").Select          '如果是,则删除两列
Selection.Delete Shift:=xlToLeft
End If
' 最后创建需要汇总和计算的单元格
.Range("c1") = "类型"
.Range("v1") = "产品名称"
.Range("w1") = "公司SKU"
.Range("g1") = "数量"
End With

如此,表格的表头处理完成,如果是一次性操作,直接用鼠标点击可以完成,如果表格数量多,且每个月都要做这个工作,则可以一劳永逸。
接下来,如果想调整英文换成中文,也可以用查找替换,比如我想将c列单元格里面的order全部替换成订单

irow = Range("a65536").End(xlUp).Row   'a单元格的最后一行赋值给变量
Range("c1:c" & irow).Select    '选中c1到c(此表格最后一行),此方法非常重要,可以判断当前表格某列最后一个单元格的行数
'将Order改为订单,同理有其他的也可以改
Selection.Replace What:="Order", Replacement:="订单", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False

arr = Range("a1:u" & irow)  '将此表格的内容存放在数组里面,可以大大提高运行速度
'接下来将需要匹配的表格赋值给变量
Set sht1 = Workbooks("参数核对表.xlsx").Sheets("SKU汇总")
Set sht2 = Workbooks("参数核对表.xlsx").Sheets("产品明细总表")

For i = 2 To irow          '建立一个循环,从第2行执行到(有多少行执行多少行)
'判断是否是空值,并建立匹配sku和明细,Excel函数VLookup需要在前面加Application.WorksheetFunction
If arr(i, 5) <> "" Then    '注意在数值里面arr(i, 5),表示第i行,第5列
Range("w" & i) = Application.WorksheetFunction.VLookup(arr(i, 5), sht1.[A:C], 3, 0)
Range("v" & i) = Application.WorksheetFunction.VLookup(arr(i, 5), sht1.[A:C], 2, 0)
End If
Next
'将表格执行完成之后,释放变量
Set sht = Nothing
Set sht1 = Nothing
Set sht2 = Nothing
Set sht3 = Nothing
End Sub

将文件夹里面的所有工作簿(workbook)里面的工作表(worksheet)合并到一个工作表里面

Sub wjhb()
Dim str As String
Dim wb As Workbook
Dim sht As Worksheet

str = Dir("E:\x\y\z\*.xls*")

For i = 1 To 100
Set wb = Workbooks.Open("E:\x\y\z\" & str)
For Each sht In wb.Sheets
If sht.Name = "订单汇总表" Then
sht.Copy after:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count).Name = Left(wb.Name, 8) & sht.Name
End If
Next
wb.Close
str = Dir
If str = "" Then
Exit For
End If
Next
End Sub

将一个工作簿里面的所有工作表的内容全部复制到一个表里面

Sub shishi()
Dim sht1, sht

Set sht = Sheets("数据")
For Each sht1 In Sheets
If sht1.Name <> "数据" Then
sht1.Select
irow = Range("a65536").End(xlUp).Row
Range("a2:k" & irow).Select
Selection.Copy
sht.Select
a = Range("a65536").End(xlUp).Row
Range("a" & a + 1).Select        '复制到B2单元格
ActiveSheet.Paste
b = Range("b65536").End(xlUp).Row
For i = a + 1 To b
Range("l" & i) = Right(Left(sht1.Name, 8), 2)
Next
End If
Next

Set sht = Nothing
End Sub

总结VBA里面的常用方法

1、Set sht = Application.ActiveSheet   将当前活动的表格赋给变量
2、With  End With 语句,针对某一个对象做的所有操作
3、 If   Elseif else  语句,逻辑判断,如果xx 则xx ,  再如果xx 则xx,否则,xx
4、   .Select   选中某个对象(可以是表格,单元格,或者一行一列,或者是一块区域)
5、Rows("1:6")    Columns("Q:R")   分别代表1-6行和QR两列
6、   .Delete  删除某个对象
7、irow = Range("a65536").End(xlUp).Row    a列的最后一行的行数赋值给变量
irow = ActiveSheet.UsedRange.Rows.Count   这个表格的最后有数据的一行的行数赋值给变量
两种方法有区别,一个是针对某一列,一个是针对表格
8、Selection.Replace What:="xx", Replacement:="yy",    对选中的区域将xx替换成yy
9、For i = x To y    建立一个循环,从x循环到y
For Each sht In wb.Sheets    建立一个循环,遍历每个工作表
10、Application.WorksheetFunction.VLookup   Excel函数前面加Application.WorksheetFunction
11、arr = Range("a1:y" & irow)    将区域赋值给数组
12、Set sht = Nothing   释放变量
13、Sheets.Add after:=Sheets(Sheets.Count)   新建一个表格在所有表格的后面
Sheets(Sheets.Count).Name = "xx"    让新建的表格名字等于xx
14、.Copy   .Paste    复制和粘贴
15、 ActiveSheet.Range(" ").RemoveDuplicates Columns:=2, Header:=xlYes
将某个区域的重复项删除
16、Range("  ").Select     Selection.Merge  对选中的区域合并单元格

最后墙裂推荐王佩丰老师的EXCEL和VBA视频教程,在网易云课堂搜索“王佩丰”即可
磨刀不误砍柴工

几行代码即可解决一个上午简单重复的工作

Python和pandas篇

import pandas as pd     #导入相应的需要匹配的数据,设置好格式
df_product_sku = pd.read_excel("/Users/mac/desktop/参数核对表.xlsx", sheet_name="SKU汇总")
df_product_sku.columns = ["sku", "产品名称", "公司sku"]   #重新设置列名

df_product_details = pd.read_excel("/Users/mac/desktop/参数核对表.xlsx", sheet_name="产品明细总表")
df_product_details1 = df_product_details[["综合SKU","成本元"]]    #只有sku和成本的两列
df_product_details1.columns = ["公司sku", "成本单价"]

df_product_details2 = df_product_details[["综合SKU","UK8"]] #只有sku和运费的两列
df_product_details2.columns = ["公司sku","物流单价"]

df_product_self = pd.read_excel("/Users/mac/desktop/参数核对表.xlsx", sheet_name="自发货汇总")
df_product_self = df_product_self[["订单号", "计费"]]
df_product_self.columns = ["订单号", "物流单价"]

df1 = pd.read_excel("/Users/mac/desktop/DS-UK.xls")
a = 0    #命名一个变量为汇率
b = []    #设置一个空的列表
# 处理表头,如果是美国则删除Q R列 删除0到6行
if df1.iloc[5, 13] == "shipping credits":    #iloc[5, 13]定位5行13列的单元格
df1 = df1.drop([16, 17], axis=1)    #drop([16, 17], axis=1) 删除16,17列
b = list(range(0, 6))
#drop(b).reset_index(drop=True) 删除1-6行,重新设置索引,并且不增加新的列
df1 = df1.drop(b).reset_index(drop=True)
else:
b = list(range(0, 5))
df1 = df1.drop(b).reset_index(drop=True)
df1.columns = df1.iloc[0]  #选取第一行作为列名
df1 = df1.drop([0]).reset_index(drop=True)  #删除第一行
list_columns = list(df1.columns)   将列名取出来成为数组
list_columns[2] = "类型"
list_columns[6] = "数量"
list_columns[8] = "订单类型"
list_columns[3] = "订单号"
if list_columns[13] == "shipping credits":
list_columns[12] = "售价美元"
list_columns[-1] = "合计美元"
a = 6.5
elif list_columns[13] == "postage credits":
list_columns[12] = "售价英镑"
list_columns[-1] = "合计英镑"
a = 8.5
else:
list_columns[12] = "售价欧元"
list_columns[-1] = "合计欧元"
a = 7.5
df1.columns = list_columns    #将表的列名改为列表
dict1 = {'Bestellung': "订单", 'Servicegebühr': '服务费', #调整类型
'übertrag': '转账', 'Versand durch Amazon Lagergebühr': '仓储费', 'Erstattung': '退货',
'Erstattung durch Rückbuchung': '退货', 'Anpassung': '调货','Blitzangebotsgebühr': '活动费',
'Commande': "订单", 'Frais de service': '服务费', 'Transfert': '转账', #调整法国的类型
'Frais de stock Expédié par Amazon': '仓储费', 'Remboursement': '退货',
'Ajustement': '调货','Tarif de la Vente Flash': '活动费',
'Pedido': "订单", 'Tarifa de prestación de servicio': '服务费', 'Transferir': '转账', #调整西班牙的类型
'Tarifas de inventario de Logística de Amazon': '仓储费', 'Reembolso': '退货',
'Ajuste': '调货','Tarif de la Vente Flash': '活动费',
'Ordine': "订单", 'Commissione di servizio': '服务费', 'Trasferimento': '转账', #调整意大利的类型
'Costo di stoccaggio Logistica di Amazon': '仓储费', 'Rimborso': '退货',
'Modifica': '调货','Tarif de la Vente Flash': '活动费',
'Order': "订单", 'Service Fee': '服务费', 'Transfer': '转账', #调整英美的类型
'Refund_Retrocharge': '仓储费', 'FBA Inventory Fee': '仓储费', 'Refund': '退货',
'Adjustment': '调货','Tarif de la Vente Flash': '活动费',
'Debt': 'FBA补贴','Lightning Deal Fee': '活动费'}
# 遍历字典循环,并且将表格的整列替换
for key,value in dict1.items():
df1.loc[df1["类型"]==key, "类型"] = value    #筛选类型这一列中等于key的单元格
df1.fillna("", inplace=True)     #用空值替换所有NAN的值,并且不创新新的表格
df1['类型'].replace("", "产品销毁费", inplace=True)    #替换类型里面空值为产品销毁费
df1 = df1.merge(df_product_sku, on="sku", how="left")   #匹配亚马逊SKU到公司的SKU,增加产品名称
df_t_sku = df1[df1["公司sku"].isnull()==False]  #匹配到有sku的
df_no_sku = df1[df1["公司sku"].isna()==True]    #没有匹配到sku的
df_t_sku_nrefund = df_t_sku[df_t_sku["类型"] != "退货"]   #  类型不是退货的
df_t_sku_refund = df_t_sku[df_t_sku["类型"] == "退货"]   #  类型是退货的
df_t_sku_nrefund = df_t_sku_nrefund.merge(df_product_details1, on="公司sku", how="left")  #匹配非退货的成本
df_t_sku_refund = df_t_sku_refund.merge(df_product_details1, on="公司sku", how="left")    #匹配退货的成本
df_t_sku_refund["成本单价"] = df_t_sku_refund["成本单价"] * -1     #退货的成本乘以-1
df_t_sku_nrefund["成本合计"] = df_t_sku_nrefund["成本单价"] * df_t_sku_nrefund["数量"]
df_t_sku_refund["成本合计"] = df_t_sku_refund["成本单价"] * df_t_sku_refund["数量"]
df_t_sku_nself = df_t_sku_nrefund[(df_t_sku_nrefund["订单类型"]=="") | \
(df_t_sku_nrefund["订单类型"]=="Amazon")] #订单非自发货
df_t_sku_self = df_t_sku_nrefund[(df_t_sku_nrefund["订单类型"]!="") & \
(df_t_sku_nrefund["订单类型"]!="Amazon")]  #订单自发货
df_t_sku_rnself = df_t_sku_refund[(df_t_sku_refund["订单类型"]=="") | \
(df_t_sku_refund["订单类型"]=="Amazon")]  #退货非自发货
df_t_sku_rself = df_t_sku_refund[(df_t_sku_refund["订单类型"]!="") & \
(df_t_sku_refund["订单类型"]!="Amazon")]  #退货自发货
df_t_sku_nself = df_t_sku_nself.merge(df_product_details2, on="公司sku", how="left")  #订单非自发货的运费
df_t_sku_rnself = df_t_sku_rnself.merge(df_product_details2, on="公司sku", how="left")  #退货非自发货的运费
df_t_sku_rnself["物流单价"] = df_t_sku_rnself["物流单价"] * -1   #退货的物流单价乘以-1
df_t_sku_self = df_t_sku_self.merge(df_product_self, on="订单号", how="left")   #订单自发货的运费
df_t_sku_rself = df_t_sku_rself.merge(df_product_self, on="订单号", how="left")  #退货自发货的运费
df_t_sku_rself["物流单价"] = df_t_sku_rself["物流单价"] * -1   #退货的物流单价乘以-1
def total_logistics(x):   定义一个函数
x["物流合计"] = x["物流单价"] * x["数量"]
total_logistics(df_t_sku_nself)
total_logistics(df_t_sku_rnself)
df_t_sku_self["物流合计"] = df_t_sku_self["物流单价"]
df_t_sku_rself["物流合计"] = df_t_sku_rself["物流单价"]
df_total = df_t_sku_nself.append([df_t_sku_rnself, df_no_sku, df_t_sku_self, df_t_sku_rself], \
ignore_index=True, sort=False)
#df_t_sku_nself[df_t_sku_nself['订单号'].duplicated(keep='first')]# 找出重复项
df_total.fillna(float(0), inplace=True)   #用0.00替换所有NAN的值
df_total["回款合计"] = df_total["合计英镑"] * a
df_total["销售合计"] = df_total["售价英镑"] * a
df_total["毛利"] = df_total.apply(lambda x: x["回款合计"] - x["物流合计"] - x["成本合计"], axis=1)
import numpy as np
#将数量这一列转换为浮点数
df_total["数量"] = df_total["数量"].apply(pd.to_numeric, errors='ignore') / 1
#以'类型', '产品名称', '公司sku'聚合   求"售价英镑", "合计英镑", "成本合计", '物流合计','数量'的合计
df2 = df_total.groupby(['类型', '产品名称', '公司sku'])\
[["售价英镑", "合计英镑", "成本合计", '物流合计','数量']].sum()
#append拼接两个表格   sort=False重新设置index
df3 = df2.loc["订单"].append(df2.loc["调货"], sort=False)
df4 = df3.groupby(['产品名称', '公司sku'])\
[["售价英镑", "合计英镑", "成本合计", '物流合计','数量']].sum()
df4 = df4.reset_index()
#df4.loc['合计'] = df4[["售价英镑", "合计英镑", "成本合计", '物流合计','数量']].apply(lambda x: x.sum())
df5 = df2.loc["退货"].reset_index()  #对列进行重新排序
df6 = df2.loc[["产品销毁费", "仓储费", "服务费", "活动费"]].reset_index()
df4["类型"] = "订单"
df5["类型"] = "退货"
df_total_1 = df4.append([df5, df6], ignore_index=True, sort=False)
s = df_total_1["类型"]
df_total_1.drop(labels=['类型'], axis=1,inplace = True)
df_total_1.insert(0, '类型', s)
df_total_1.loc['合计'] = df_total_1[["售价英镑", "合计英镑", "成本合计", '物流合计','数量']].apply(lambda x: x.sum())
print(df_total_1)

总结python、pandas里面的常用方法
读取工作簿里面的某个工作表

pd.read_excel("/Users/mac/desktop/   .xlsx", sheet_name="")

设置表格的列名

df.columns = ["   "]

删除x 和y 列

df = df.drop([x, y], axis=1)

删除表格里面b(0-4)行,并且重新设置索引

b = list(range(0, 5))
df = df.drop(b).reset_index(drop=True)

选取行列和单元格的操作

*loc方法*
#行
df.loc['6']           # 行名称为6的行
df.loc['5':'7']       # 行名称为5至7的行,注意是前闭后闭
df.loc[['5', '7']]    # 行名称为5和7的行
#列
df.loc[:, 'B']        # 列名称为'B‘的列
df.loc[:, 'A':'C']    # 列名称为A至C的列,注意是前闭后闭
df.loc[:, ['A', 'C']] # 列名称为A和C的列
#块
df.loc['5':'7', 'A':'C']       # 行名称为5至7,列名称为A~C的一块数据
df.loc[['5', '7'], ['A', 'C']] # 行名称为5和7,列名称为A和C的一块数据
df.loc['5':'7', ['A', 'C']]    # 行名称5至7,列名称A和C的一块数据
df.loc[['5', '7'], 'A':'C']    # 行名称为5和7,列名称为A~C的一块数据
#单元格
df.loc['5', 'A']   # 行名称为5,列名称为A的单元格数据
df.at['5', 'A']    # 同loc但速度快点

*iloc方法*
#行
df.iloc[1]          # 第2行
df.iloc[0:3]        # 前3行
df.iloc[[0, 3]]     # 第1第4行
#列
df.iloc[:, 1]       # 第2列
df.iloc[:, 0:3]     # 前3列
df.iloc[:, [0, 3]]  # 第1第4列
#块
df.iloc[0:3, 0:3]          # 前3行,前3列的一块数据
df.iloc[[0, 3],  [0, 3]]   # 第1第4行,第1第4列的一块数据
df.iloc[0:3, [0, 3]]       # 前3行,第1第4列的一块数据
df.iloc[[0, 3], 0:3]       # 第1第4行,前3列的一块数据
#单元格
df.iloc[1, 1]   # 第1行,第1列的单元格
df.iat[1, 1]    # 同iloc但速度快点

总的来说,loc方法针对名称,iloc方法针对行列所在的位置,都是先行后列

替换表格里面的值

df.dropna(axis=0, how='any')   # 行里有缺失值就丢掉,如果行里所有值是缺失值才丢掉可以how='all'      axis=0对行操作
df.dropna(axis=1, how='any')    # 列里有缺失值就丢掉 axis=1对列操作
df.fillna("", inplace=True)     #用空值替换所有NAN的值
df['x'].replace("", ",", inplace=True)    #用逗号替换x列的所有的空值

匹配和查找,merge类似VLOOKUP

df = df.merge(df1, on="x", how="left")   #df和df1两个表格以x列匹配,按照df的x列进行匹配

选择某列不为空的值

df[df["x"].isna()==True]   #x列非空的所有数据

多条件筛选

df = df[(df["x"]=="") | (df["y"]==1)]  #表中x列等于空值,或者y列等于1的所有数据
df = df[(df["x"]> 8) & (df["y"]<= 6 )]  #表中x列大于8,且y列小于等于6的所有数据
#  |类似or    &类似and

改变列的格式 apply方法,将函数施加给对象

df["x"] = df["x"].apply(pd.to_numeric, errors='ignore')#将x列转换为数字

创建透视表

df = df.pivot_table(values=["x", "y"],index=['a'], columns=['b'], aggfunc=[np.sum],  margins=True)
#a为行,b为列,将x列和y列进行求和,并且有合计项的透视表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: