pandas (day4)

本文介绍了如何使用PythonPandas处理电商数据,包括合并Excel数据、按城市和订单ID分组计算销售额、解决重复金额问题、使用层次索引、空值填充和数据清洗,以及不同数据呈现方式如二维表、交叉表和透视表的运用。
摘要由CSDN通过智能技术生成

一. 找到各个城市中销售额 第二 的订单

1.1 获取数据

# 先将三个excel 进行融合   一个excel 里面有三个 sheet
data = pd.read_excel("./teacher/电商数据.xlsx",sheet_name=["订单信息","订单详情","地区信息"])
df = pd.merge(pd.merge(data["订单详情"],data["订单信息"]),data["地区信息"])

1.2  根据城市进行分组,再根据订单ID进行分组,对每个订单金额进行求和,再按照金额 倒叙 排列

方法 1
df.groupby(by = "城市").apply(lambda x: x.groupby(by = "订单ID").订单金额.sum().sort_values(ascending = False))

这样会存在问题, 相同金额的订单,会分别排在 第一名 和 第二名 这样

城市  订单ID  
三亚  230372    183.00
     226977    129.90          这两个都是 129.9
     228703    129.90          
     227758    103.15
     228004     99.00

方法2
# df.groupby(by = "城市").apply(lambda x: x.groupby(by = "订单ID").订单金额.sum().sort_values(ascending = False))

def fo(x):
    s1 = x.groupby(by = "订单ID").订单金额.sum().sort_values(ascending = False)  # 这里的 x 仍然代表 每一个 df
    # s1 获取的是按照订单id 计算 的 订单金额 的总和  并按照 金额从大到小排序
    if s1.shape[0] == 1:   # s1 返回的是series,如果他的(x,)x是1,就返回唯一值,否则返回第二大的值
        return s1.iloc[0]
    else:
        return s1.iloc[1]

老二 = df.groupby(by = "城市").apply(fo).reset_index().rename(columns = {0:"金额"})
这里输出的都是每个城市 订单金额第二的城市 和金额

	城市	金额
0	三亚	129.90
1	三明	1380.21
2	上海	998.00
3	上饶	2110.70
4	东莞	1298.10

    已经求出来第二消费高的城市了,因为还需要知道订单信息,需要和df表合并

    但是 "老二" 表  已经是聚合过的 (按照城市  计算过sum) ,所以 df表也需要 groupby 城市 和 订单id

1 . df表 先聚合 
df.groupby(by=["城市","订单ID"]).订单金额.sum().reset_index()

城市	订单ID	订单金额
0	三亚	226977	129.90
1	三亚	227758	103.15
2	三亚	228004	99.00
3	三亚	228703	129.90
4	三亚	229312	91.05


2. 两表连接 , 找到 订单金额 为 第二名 的 订单信息
pd.merge(gp,老二,left_on =["城市","订单金额"], right_on= ["城市","金额"],how = "inner")
方法2
def fo(x): #x 依然代表 每个df
    s1 = x.groupby("订单ID").agg({"订单金额":"sum"}).sort_values(by="订单金额",ascending=False)  
    return s1

a = df.groupby(by="城市").apply(fo)
这里是获取到 按照城市 金额从大到小的 信息


def foo(x):
    x["排名序号"] =  x.订单金额.rank(method="dense",ascending=False) # 加一列排名序号
    return x.query("排名序号==2")

a.reset_index().groupby(by=["城市"]).apply(foo)  #只拿排名序号为2的信息

二 . 层次索引

  • stack : 把列索引 转换成 行索引
  • unstack : 把行索引 转换成 列索引
    • names=['国家', '省份', '订单年份', '订单月份', None]
b = df.groupby(by=[ '国家', '省份', '订单年份', '订单月份']).apply(lambda x : x.金额.sum()).unstack(level=[0,1]).fillna(0)
            
                                                                        level 0 是国家  1 是省份  unstack 是把行索引 变成了列

三 . 空值填充

  • fillna - value : 指定填充  fillna(0) 
    •   method : ffill从前方找内容填充 
    •   bfill从后方找内容填充
  • 演示数据.区域.str.contains("汇总") contains 是包含汇总字段的
演示数据 = pd.read_excel("./02.行列管理及筛选.xlsx",sheet_name="删除间隔行").iloc[:,:3]
演示数据
	第三季度各区预计销售额汇总	列1	列2
0	区域	产品分类	预计销售额
1	东区	服装	372960.1584
2	NaN	   辅助用品	161573.9614
3	NaN	    配件	3635719.8314
4	NaN	   自行车	22059205.9118
5	东区汇总	NaN	    26229459.863
6	南区	服装	281120.2381



修改列名 

演示数据.columns = 演示数据.iloc[0]
将 0	区域	产品分类	预计销售额  这一行 作为 列名



fillna - value : 指定填充 
        - method : ffill从前方找内容填充 
                   bfill从后方找内容填充

演示数据.区域 = 演示数据.区域.fillna(method="ffill",axis=0)
将 区域 这一列 的空值 按照从前方找内容方式 填充
	区域	产品分类	预计销售额
0	区域	产品分类	预计销售额
1	东区	服装	372960.1584
2	东区	辅助用品	161573.9614
3	东区	配件	3635719.8314
4	东区	自行车	22059205.9118
5	东区汇总	NaN	26229459.863
6	南区	服装	281120.2381


将 各区汇总去除
演示数据 = 演示数据.loc[~演示数据.区域.str.contains("汇总")]

演示数据.区域.str.contains("汇总") 是挑选 字段 中 有汇总的
~ 是 没有汇总的

四. 空值删除

  • dropna(subset=["产品分类"])   指定删除 产品分类的空值

五. 数据清洗 

5.1  有三个csv 文件 是 "state-"  开头 ".csv" 结尾 的文件 

glob.glob("./state-*.csv")

返回的是 一个列表  ,内容都是  state- 开头  .csv 结尾的文件路径

['.\\state-abbrevs.csv', '.\\state-areas.csv', '.\\state-population.csv']

 5.2 读取数据(多个)

for f in filenames:
    display(pd.read_csv(f).head(2))


d = dict()
for f in filenames:
    n = f.split("-")[1].split(".")[0]
    d[n] = pd.read_csv(f)

n 是 key, 分别是 abbrevs areas population
d[n] 是 值 ,就是 pd.read_csv(f) 读取的内容
 
所有 d["abbrevs"]  就可以获取内容

5.3  rename 改列名  merge进行合并

d["areas"] = d["areas"].rename(columns = {"area (sq. mi)":"area"} )
d["population"].rename(columns= {"state/region":"abbreviation"},inplace = True)


pop_abb = pd.merge(d["population"],d["abbrevs"],how = 'outer')

5.3  对空值进行 统计 

	abbreviation	ages	year	population	state
0	AL	under18	2012	1117489.0	Alabama
1	AL	total	2012	4817528.0	Alabama
2	AL	under18	2010	1130966.0	Alabama
3	AL	total	2010	4785570.0	Alabama
4	AL	under18	2011	1125763.0	Alabama
...	...	...	...	...	...
2539	USA	total	2010	309326295.0	NaN
2540	USA	under18	2011	73902222.0	NaN
2541	USA	total	2011	311582564.0	NaN
2542	USA	under18	2012	73708179.0	NaN
2543	USA	total	2012	313873685.0	NaN

pop_abb 原数据 是以上所示

  •  可以使用 isnull 用bool值看是否为空值, 然后通过 sum() 进行计算,因为True 是 1, False 是 0
pop_abb.isnull().sum()

abbreviation     0
ages             0
year             0
population      20
state           96
dtype: int64

这样可以看出来 population  和 state 都为空值列 

5.4 对空值进行填

1   获取 state 那一列 中 为空的所有行数据
pop_abb.loc[pop_abb.state.isnull()]

	abbreviation	ages	year	population	state
2448	PR	under18	1990	NaN	NaN
2449	PR	total	1990	NaN	NaN
2450	PR	total	1991	NaN	NaN
2451	PR	under18	1991	NaN	NaN
2452	PR	total	1993	NaN	NaN
...	...	...	...	...	...
2539	USA	total	2010	309326295.0	NaN
2540	USA	under18	2011	73902222.0	NaN
2541	USA	total	2011	311582564.0	NaN
2542	USA	under18	2012	73708179.0	NaN
2543	USA	total	2012	313873685.0	NaN

2.  state 列 是依据 abbreviation 进行填充的,查看 state列为空的 abbreviation 去重后有哪些
pop_abb.loc[pop_abb.state.isnull()].abbreviation.unique()

array(['PR', 'USA'], dtype=object)


3.  建立 字典 ,建立 abbreviation(键) 和 state(值)的关系
dict_abb = {"PR":"Puerto Rico","USA":"USA"}

4. k是pr 和 usa, 当 abbreviation为 usa 或者 pr 时,对应的state 变为 对应的值
for k in dict_abb : 
    pop_abb.loc[pop_abb.abbreviation == k,"state"] = dict_abb[k] 

5. pop_abb.isnull().sum()
abbreviation     0
ages             0
year             0
population      20
state            0
dtype: int64

可以看出 state 空白值已被全部填充

六 . 不同的数据呈现方式

1. 二维表

6.1 unstack()  行索引 变成 列索引
data.groupby(by = ["订单年份","订单月份"]).金额.sum().index 

 names=['订单年份', '订单月份'])  

data.groupby(by = ["订单年份","订单月份"]).金额.sum().unstack(level = 0)
这是年份,按照上面 index  年份 月份来的

6.2  交叉表
pd.crosstab(data["订单月份"],data["订单年份"])
6.3 透视 (数据必须是唯一的)

pd.pivot(data , index , columns)    透视数据 ,但是都是去重的(唯一的)

d = data.groupby(by = ["订单年份","订单月份"]).agg({"金额":"sum"}).reset_index()

	订单年份	订单月份	金额
0	2013	7	196650
1	2013	8	172625
2	2013	9	23750
3	2013	10	189475
4	2013	11	271125
5	2014	2	103762
6	2014	3	13906

根据年份 月份 计算 的话,有些月份 数据会消失 ,因为没有订单的数据 


pd.pivot(d,index = ["订单月份"], columns = ["订单年份"], values=["金额"])

订单年份	2013	2014	2015	2016
订单月份				
1	NaN	NaN	NaN	56879.0
2	NaN	103762.0	NaN	71044.0
3	NaN	13906.0	4098.0	60800.0
4	NaN	6775.0	NaN	48793.0
5	NaN	NaN	NaN	106246.0
6	NaN	NaN	NaN	25037.0
7	196650.0	NaN	639547.0	8922.0
8	172625.0	NaN	81340.0	NaN
9	23750.0	NaN	98361.0	NaN
10	189475.0	NaN	89448.0	NaN
11	271125.0	NaN	86645.0	NaN
12	NaN	NaN	229448.0	NaN
6.4  透视表 pd.pivot_table
pd.pivot_table(data,index = ["订单月份"], columns = ["订单年份"], values=["金额"],aggfunc="sum")

2. 将二维表转换 为 一维表

原数据
matrix = pd.pivot_table(data,index = ["订单月份"], columns = ["订单年份"], values=["金额"],aggfunc="sum")
matrix

	金额
订单年份	2013	2014	2015	2016
订单月份				
1	NaN	NaN	NaN	56879.0
2	NaN	103762.0	NaN	71044.0
3	NaN	13906.0	4098.0	60800.0
4	NaN	6775.0	NaN	48793.0
5	NaN	NaN	NaN	106246.0
6	NaN	NaN	NaN	25037.0
7	196650.0	NaN	639547.0	8922.0
8	172625.0	NaN	81340.0	NaN
9	23750.0	NaN	98361.0	NaN


pd.melt()  将二维表转成一维表
vec = pd.melt(matrix).rename(columns = {"value":"金额"})
vec

	None	订单年份	金额
0	金额	2013	NaN
1	金额	2013	NaN
2	金额	2013	NaN
3	金额	2013	NaN
4	金额	2013	NaN
5	金额	2013	NaN
6	金额	2013	196650.0
7	金额	2013	172625.0
8	金额	2013	23750.0
9	金额	2013	189475.0

生成一列 订单月份  1-12 循环 四次
vec["订单月份"] = list(range(1,13))* matrix.shape[1]

将 生成一列 新的序列
vec.dropna().reset_index(drop = True)

案例 中国各个省份 销售了那些 品类

订单ID	订单年份	订单月份	产品名称	产品子类别	产品类别	省份	国家	数量	单价	金额
0	a01	2015	11	Touring Tire Tube	车胎和内胎	配件	黑龙江	中国	1	5	5
1	a02	2015	11	Short-Sleeve Classic Jersey S	骑行服	服装	内蒙古	中国	1	54	54
2	a03	2015	11	Touring-1000 Blue 46	旅行自行车	自行车	吉林	中国	1	2384	2384
3	a04	2015	7	Mountain-200 Silver 38	山地自行车	自行车	辽宁	中国	1	2320	2320
4	a05	2015	11	Touring Tire	车胎和内胎	配件	河北	中国	1	29	29
a = data.query("国家 == '中国'").groupby(by=["省份"]).apply(lambda x: "/".join(x["产品类别"].unique())).reset_index().rename(columns = {0:"品类们"})

按照 中国  各省份 进行分类 , .join 拼接 多个产品。 并进行 去重操作


b = data.query("国家 == '中国'").groupby(by=["省份"]).金额.sum().reset_index()
计算各个省份 的销售额


pd.concat([a,b],axis=1).iloc[:,[1,2,3]]
将 a b  进行左右拼接 去列 1,2,3列

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值