1001系列之案例0001如何从淘宝销售数据集中挖掘有效信息

本案例重点有二:
重点一在于如何修改数据类型以降低内存占用,这对大数据非常重要;
重点二在于分析变量之间的关系,单变量分布,双变量相关或方差分析,多变量回归或分类;

一、数据基本信息

#导入必要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
#指定工作路径以导入数据或者存入数据
import os
os.chdir("D:\Data\File")
#可视化的必要设置
%matplotlib inline
plt.rcParams["font.sans-serif"] = ["KAITI"]
plt.rcParams["axes.unicode_minus"] = False

1.1 数据集查看

#导入数据并查看前两行
df = pd.read_csv("taobao_data.txt")
df.head(5)
宝贝 价格 成交量 卖家 位置
0 新款中老年女装春装雪纺打底衫妈妈装夏装中袖宽松上衣中年人t恤 99.0 16647 夏奈凤凰旗舰店 江苏
1 中老年女装清凉两件套妈妈装夏装大码短袖T恤上衣雪纺衫裙裤套装 286.0 14045 夏洛特的文艺 上海
2 母亲节衣服夏季妈妈装夏装套装短袖中年人40-50岁中老年女装T恤 298.0 13458 云新旗舰店 江苏
3 母亲节衣服中老年人春装女40岁50中年妈妈装套装夏装奶奶装两件套 279.0 13340 韶妃旗舰店 浙江
4 中老年女装春夏装裤大码 中年妇女40-50岁妈妈装夏装套装七分裤 59.0 12939 千百奈旗舰店 江苏

1.2 修改数据类型以节省空间

# 查看数据集的数据类型、数量和内存空间
df.info(memory_usage="deep")     #memory_usage参数可以查看数据集导入内存需要占用多少内存,这在导入大型数据集时非常有用
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   宝贝      100 non-null    object 
 1   价格      100 non-null    float64
 2   成交量     100 non-null    int64  
 3   卖家      100 non-null    object 
 4   位置      100 non-null    object 
dtypes: float64(1), int64(1), object(3)
memory usage: 33.4 KB
df.memory_usage()
Index    128
宝贝       800
价格       200
成交量      200
卖家       800
位置       464
销售额      400
dtype: int64
df.memory_usage().sum()
2992

以上可知有五个变量,一个整型,一个浮点型,三个对象型,数据集大小是33.4KB,长度为100行;

#找出卖家这一列中名字最长的店的长度
df["卖家"].apply(lambda x:len(x)).max()
15
#查看各个变量的数据的最大值,以确定是否更改数据类型以减少占用内存
#“宝贝”这一变量的数据类型是Object,它的内容是文字,既不能转换为数值,也不能转换为类别型,只能保留其数据类型
#价格的数据类型为浮点型,最大值为698.00,保留两位小数,numpy中float有float16(半精度),float32,float64三种,半精度可以表示的最大数为65504,最小数6.104×10^(-5),所以一般情况float316就够用了
#成交量的数据类型是整型,最大值为16647,最小值为3956,所以可以转换为uint16(无符号整数(0 to 65535)
#卖家的数据类型是Object,有85个唯一值,而且长度最长有15个汉字,占30个字节,如果转换成类别型数据比Object节省空间
#位置是省级行政区,可以转换为类别型数据
df["价格"] = df["价格"].astype("float16")
df.info(memory_usage="deep")  #可以看到内存减少了0.6KB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   宝贝      100 non-null    object 
 1   价格      100 non-null    float16
 2   成交量     100 non-null    int64  
 3   卖家      100 non-null    object 
 4   位置      100 non-null    object 
dtypes: float16(1), int64(1), object(3)
memory usage: 32.8 KB
df["成交量"] = df["成交量"].astype("uint16")
df.info(memory_usage="deep")  #可以看到内存又减少了0.6KB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   宝贝      100 non-null    object 
 1   价格      100 non-null    float16
 2   成交量     100 non-null    uint16 
 3   卖家      100 non-null    object 
 4   位置      100 non-null    object 
dtypes: float16(1), object(3), uint16(1)
memory usage: 32.2 KB
df["位置"] = df["位置"].astype("category")
df.info(memory_usage="deep")  #可以看到内存减少了7.3KB,减少的最多
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype   
---  ------  --------------  -----   
 0   宝贝      100 non-null    object  
 1   价格      100 non-null    float16 
 2   成交量     100 non-null    uint16  
 3   卖家      100 non-null    object  
 4   位置      100 non-null    category
dtypes: category(1), float16(1), object(2), uint16(1)
memory usage: 24.9 KB
df["卖家"] = df["卖家"].astype("category")
df.info(memory_usage="deep")  #看到内存反而升高了2.2KB,这说明Object数据类型里容纳的数据长度不齐,对短的类别少的转换为category比较有利
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype   
---  ------  --------------  -----   
 0   宝贝      100 non-null    object  
 1   价格      100 non-null    float16 
 2   成交量     100 non-null    uint16  
 3   卖家      100 non-null    category
 4   位置      100 non-null    category
dtypes: category(2), float16(1), object(1), uint16(1)
memory usage: 27.1 KB
df["卖家"] = df["卖家"].astype("object")
df.info(memory_usage="deep")  #再转回原来的object但是内存并没有变回原来的,这有可能是没有进行压缩
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype   
---  ------  --------------  -----   
 0   宝贝      100 non-null    object  
 1   价格      100 non-null    float16 
 2   成交量     100 non-null    uint16  
 3   卖家      100 non-null    object  
 4   位置      100 non-null    category
dtypes: category(1), float16(1), object(2), uint16(1)
memory usage: 26.6 KB

通过上述转换,从最开始的33.4KB降到26.6KB,幅度达到20%,如果是大数据集,这是惊人的效率。

1.3 查看数据集的描述性统计特征

#查看数据集的描述性统计特征,如果不指定参数,则默认只描述数值型变量,如果指定“includes=”参数,则可以看到所有数据类型的统计特征
df.describe(include="all")
宝贝 价格 成交量 卖家 位置
count 100 100.000000 100.00000 100 100
unique 99 NaN NaN 85 8
top 中老年人女装套装妈妈装夏装大码奶奶装40-50岁60短袖T恤70两件套 NaN NaN 香颜旗舰店 江苏
freq 2 NaN NaN 3 44
mean NaN 231.669000 6388.93000 NaN NaN
std NaN 130.971061 2770.07536 NaN NaN
min NaN 29.000000 3956.00000 NaN NaN
25% NaN 128.750000 4476.50000 NaN NaN
50% NaN 198.000000 5314.50000 NaN NaN
75% NaN 298.000000 7053.75000 NaN NaN
max NaN 698.000000 16647.00000 NaN NaN
#对于小数据集,还可以通过一个库统览数据集的特征———pandas_profiling;
#但是对于超过十万行的数据量该功能会占用大量内存,加载变慢
import pandas_profiling
report = pandas_profiling.ProfileReport(df)
report.to_file("census_report.html")

二、变量间关系分析及可视化描述

上面已知五个变量,两个数值型,三个文字型。先对两个数值型变量进行分析

2.1 数值型变量

#看价格的分布情况
plt.figure(figsize=(8,6),dpi=50)
sns.displot(df["价格"],bins=20)
plt.xlabel("价格")
plt.ylabel("频率",rotation=0)
plt.show()

在这里插入图片描述

#调整箱子,再看价格的分布情况
plt.figure(figsize=(6,4))
sns.displot(df["价格"],bins=40)
plt.xlabel("价格")
plt.ylabel("频率",rotation=0)
plt.tight_layout()
plt.show()

在这里插入图片描述

价格的最高在100元附近,次高在200元附近,第三高在300元附近,不是正态分布,右偏形态

#看成交量的分布
plt.figure(figsize=(10,12),dpi=100)
sns.displot(df["成交量"],bins=40,color="r")
plt.xlabel("成交量")
plt.ylabel("频率",rotation=0)
plt.show()

在这里插入图片描述

成交量的分布呈现指数分布

#查看价格与成交量直接是否有相关关系
plt.figure(figsize=(10,6),dpi=100)
plt.scatter(df["价格"],df["成交量"],color="r")
plt.xlabel("价格")
plt.ylabel("成交量",rotation=0)
plt.show()

在这里插入图片描述

从图上看相关关系好像不大,接下来计算一下协方差和相关系数

df[["价格","成交量"]].corr()  
价格 成交量
价格 1.000000 -0.026771
成交量 -0.026771 1.000000

通过计算相关系数,也得出两者没有相关关系,并不是价格越低成交量越大

2.2 文本型变量

#查看有多少卖家,出现次数前10的卖家是哪些
len(df['卖家'].unique())
85
df[["卖家","位置"]].groupby("卖家").count().sort_values("位置",ascending=False)[:15].T
卖家 蒲洛妃旗舰店 朵莹旗舰店 金星靓雅服装店 简港旗舰店 香颜旗舰店 loueddssd倍艾旗舰店 妃莲慕旗舰店 潮流前线9170 浅恋旗舰店 拓芙尼旗舰店 欧芮嘉旗舰店 梵忆轩旗舰店 第二号鞋铺 歌迪凤凰旗舰店 时尚_miss
位置 3 3 3 3 3 2 2 2 2 2 1 1 1 1 1
df[["卖家","位置"]].groupby("卖家").count().sort_values("位置",ascending=False)[:15].plot()

在这里插入图片描述

df[["位置","卖家"]].groupby("位置").count().sort_values("卖家",ascending=False)[:15].T
位置 江苏 浙江 上海 湖北 北京 河北 广东 河南
卖家 44 28 10 7 6 3 1 1
df[["位置","卖家"]].groupby("位置").count().sort_values("卖家",ascending=False)[:15].plot(kind="bar")
<matplotlib.axes._subplots.AxesSubplot at 0x236b48ddf60>

在这里插入图片描述

len(df['宝贝'].unique())  #宝贝没有重复的
99

2.3 不同变量之间的组合

#不同卖家之间成交量的对比
df[["卖家","成交量"]].groupby("卖家").mean().sort_values("成交量",ascending=False)[:10].T
卖家 夏奈凤凰旗舰店 夏洛特的文艺 云新旗舰店 韶妃旗舰店 千百奈旗舰店 依安雅旗舰店 千百萌旗舰店 zxtvszml ceo放牛 依诗曼妮
成交量 16647.0 14045.0 13458.0 13340.0 12939.0 12664.0 12398.0 12087.0 11655.0 11125.0
df[["卖家","成交量"]].groupby("卖家").mean().sort_values("成交量",ascending=False)[:10].plot()

在这里插入图片描述

#不同卖家之间平均价格的对比
df[["卖家","价格"]].groupby("卖家").mean().sort_values("价格",ascending=False)[:10].T
卖家 简狐旗舰店 潮流前线9170 发财花旗舰店 歌迪凤凰旗舰店 蕴涵旗舰店 玛依恋旗舰店 衣之绒旗舰店 时尚_miss 尼罗鹤旗舰店 qianyaofushi888
价格 698.0 638.0 558.0 528.0 498.0 399.0 399.0 398.0 398.0 398.0
df[["卖家","价格"]].groupby("卖家").mean().sort_values("价格",ascending=False)[:10].plot()

在这里插入图片描述

#不同位置的卖家的销量对比
df[["位置","成交量"]].groupby("位置").mean().sort_values("成交量",ascending=False)[:10].plot()

在这里插入图片描述

#不同位置的卖家的均价对比
df[["位置","价格"]].groupby("位置").mean().sort_values("价格",ascending=False)[:10].plot()

在这里插入图片描述

#新增一个销售额列,看看价格销量的变化趋势
df["销售额"] = df["价格"]* df["成交量"]/1000
cot = list(np.arange(len(df["价格"])))
plt.figure(figsize=(10,12),dpi=100)
plt.scatter(cot,df["价格"])
plt.scatter(cot,df["成交量"],c="red")
plt.scatter(cot,df["销售额"],c="orange")
plt.xlabel("卖家")
plt.ylabel("数量",rotation=0)
plt.show()

在这里插入图片描述

2.4 分类变量对数值型变量的影响——方差分析

from scipy import stats 
df["位置"].unique()
['江苏', '上海', '浙江', '湖北', '河北', '河南', '北京', '广东']
Categories (8, object): ['江苏', '上海', '浙江', '湖北', '河北', '河南', '北京', '广东']
d1 = df[df["位置"] == "江苏"]['成交量']
d2 = df[df["位置"] == "上海"]['成交量']
d3 = df[df["位置"] == "浙江"]['成交量']
d4 = df[df["位置"] == "湖北"]['成交量']
d5 = df[df["位置"] == "河北"]['成交量']
d6 = df[df["位置"] == "河南"]['成交量']
d7 = df[df["位置"] == "北京"]['成交量']
d8 = df[df["位置"] == "广东"]['成交量']
dd=[d1,d2,d3,d4,d5,d6,d7,d8]
f,p = stats.f_oneway(*dd)
print(f,p)
0.9960034164625489 0.4393090856247839

正常情况下,可以算出F值和p值,但是在这里每个组的样本数量相差太大,因此会结果不准确

三、实际问题解决

1.哪个地方的成交量最多

2.哪个卖家成交量最多

3.哪个宝贝成交量最多

4.哪个商家的成交额最多

Most_amount = df[["位置","成交量"]].groupby("位置").sum().sort_values("成交量",ascending=False)
Most_amount[:1]  #成交量最多的是江西
成交量
位置
江苏 309360.0
Most_amount1 = df[["卖家","成交量"]].groupby("卖家").sum().sort_values("成交量",ascending=False)
Most_amount1[:1]  #成交量最多的是简港旗舰店
成交量
卖家
简港旗舰店 24423
Most_amount1 = df[["宝贝","成交量"]].groupby("宝贝").sum().sort_values("成交量",ascending=False)
Most_amount1[:1]  #成交量最多的是新款中老年女装春装雪纺打底衫妈妈装夏装中袖宽松上衣中年人t恤
成交量
宝贝
新款中老年女装春装雪纺打底衫妈妈装夏装中袖宽松上衣中年人t恤 16647
Most_amount1 = df[["卖家","销售额"]].groupby("卖家").sum().sort_values("销售额",ascending=False)
Most_amount1[:1]  #成交量最多的是简港旗舰店
销售额
卖家
潮流前线9170 6935.335938

透视表

#透视表适用于类别变量比较少的,数量太多难以透视
pt = pd.pivot_table(df,index="位置",values="成交量",aggfunc=["mean","sum"])
pt
mean sum
成交量 成交量
位置
上海 6801.500000 68015
北京 4519.333333 27116
广东 5164.000000 5164
江苏 7030.909091 309360
河北 6050.666667 18152
河南 5986.000000 5986
浙江 5779.500000 161826
湖北 6182.000000 43274

猜你喜欢

转载自blog.csdn.net/lqw844597536/article/details/117260416