4 Python数据分析 淘宝母婴用品数据分析案例

Python数据分析

1 淘宝母婴用品数据分析案例

1.1 数据介绍

数据来源:Baby Goods Info Data

1.2 字段介绍

婴儿信息数据 Tianchi_mum_baby.csv

字段描述补充
user_id用户id
birthday出生日期格式yyymmdd,例如2011.11.11
gender性别0:女性,1:男性,2:未知

购买历史数据 Tianchi_mum_baby_trade_history.csv

字段描述补充
item_id商品id
user_id用户id
cat_id商品二级分类
cat1商品一级分类
property商品属性
buy_mount购买数量
day购买日期格式yyymmdd,例如2011.11.11
1.3 数据分析
1.3.1 购买历史数据
1.3.1.1 数据导入
import numpy as np
import pandas as pd
from pandas import Series, DataFrame

# 购买历史数据
trade_history_df = pd.read_csv('./(sample)sam_tianchi_mum_baby_trade_history.csv')
trade_history_df.head()
'''
	user_id 	auction_id 		cat_id 		cat1 		property 											buy_mount 	day
0 	786295544 	41098319944 	50014866 	50022520 	21458:86755362;13023209:3593274;10984217:21985... 	2 			20140919
1 	532110457 	17916191097 	50011993 	28 			21458:11399317;1628862:3251296;21475:137325;16... 	1 			20131011
2 	249013725 	21896936223 	50012461 	50014815 	21458:30992;1628665:92012;1628665:3233938;1628... 	1 			20131011
3 	917056007 	12515996043 	50018831 	50014815 	21458:15841995;21956:3494076;27000458:59723383... 	2 			20141023
4 	444069173 	20487688075 	50013636 	50008168 	21458:30992;13658074:3323064;1628665:3233941;1... 	1 			20141103
'''
1.3.1.2 数据清洗
  1. 商品属性字段property是由编号组成,无法具体分析,进行删除处理。
trade_history_df.drop(labels='property', axis=1, inplace=True)
trade_history_df.info()
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 29971 entries, 0 to 29970
Data columns (total 6 columns):
 #   Column      Non-Null Count  Dtype
---  ------      --------------  -----
 0   user_id     29971 non-null  int64
 1   auction_id  29971 non-null  int64
 2   cat_id      29971 non-null  int64
 3   cat1        29971 non-null  int64
 4   buy_mount   29971 non-null  int64
 5   day         29971 non-null  int64
dtypes: int64(6)
memory usage: 1.4 MB
'''
  1. 将购买日期字段day数据转换成时间类型。

to_datetime方法用于将数据转换成时间类型。

pd.to_datetime(arg,format = None,...)

参数format:指定原始数据的格式。

trade_history_df['day'] = pd.to_datetime(trade_history_df['day'], format='%Y%m%d')
trade_history_df.head()
'''
 	user_id 	auction_id 		cat_id 		cat1 		buy_mount 	day
0 	786295544 	41098319944 	50014866 	50022520 	2 			2014-09-19
1 	532110457 	17916191097 	50011993 	28 			1 			2013-10-11
2 	249013725 	21896936223 	50012461 	50014815 	1 			2013-10-11
3 	917056007 	12515996043 	50018831 	50014815 	2 			2014-10-23
4 	444069173 	20487688075 	50013636 	50008168 	1 			2014-11-03
'''
  1. 检查是否存在空值
trade_history_df.isnull().any(axis=0)
'''
user_id       False
auction_id    False
cat_id        False
cat1          False
buy_mount     False
day           False
dtype: bool
'''
  1. 检查购买数量字段buy_mount是否存在异常值
trade_history_df['buy_mount'].max()  # 10000
trade_history_df['buy_mount'].min()  # 1
(trade_history_df['buy_mount'] <= 0).sum()  # 0
1.3.1.3 数据分析
  1. 查看数据的日期范围,显示出数据集的最早购买日期和最晚购买日期。

方式1:

df = trade_history_df.sort_values(by='day', axis=0, ascending=True)
df.head(1)['day']  # 20120702
df.tail(1)['day']  # 20150205

方式2:

trade_history_df['day'].min(), trade_history_df['day'].max()
# (Timestamp('2012-07-02 00:00:00'), Timestamp('2015-02-05 00:00:00'))
  1. 分析用户购买情况,判断用户趋向于多次购买商品还是只购买一次商品。
trade_history_df['user_id'].nunique()  # 用户总数:29944

(trade_history_df.groupby(by='user_id')['day'].count() == 1).value_counts()
'''
True     29919  # 只购买一次商品的用户数量
False       25  # 多次购买商品的用户数量
Name: day, dtype: int64
'''
1.3.2 婴儿信息数据
1.3.2.1 数据导入
user_df = pd.read_csv('./(sample)sam_tianchi_mum_baby.csv')
user_df.head()
'''
	user_id 	birthday 	gender
0 	2757 		20130311 	1
1 	415971 		20121111 	0
2 	1372572 	20120130 	1
3 	10339332 	20110910 	0
4 	10642245 	20130213 	0
'''
1.3.2.2 数据清洗
  1. 将出生日期字段birthday数据转换成时间类型。
user_df['birthday'] = pd.to_datetime(user_df['birthday'], format='%Y%m%d')
  1. 检查是否存在缺失数据。
user_df.isnull().any(axis=0)
'''
user_id     False
birthday    False
gender      False
dtype: bool
'''
  1. 处理性别字段中的异常数据。
user_df['gender'].value_counts()
'''
0    489
1    438
2     26
Name: gender, dtype: int64
'''

性别字段中数值2表示未知性别,这里被视为异常数据。

user_df = user_df.loc[~(user_df['gender'] == 2)]
user_df['gender'].value_counts()
'''
0    489
1    438
Name: gender, dtype: int64
'''
1.3.2.3 数据分析

查看男女比例

male_to_female_series = user_df['gender'].value_counts()
male_to_female_series[0] / male_to_female_series[1]  # 1.1164383561643836
1.3.3 汇总购买历史数据和婴儿信息数据
1.3.3.1 汇总
total_df = pd.merge(trade_history_df_temp, user_df_temp, on='user_id', how='outer') 
1.3.3.2 数据分析
  1. 查看用户复购程度
    方式1
    仅考虑购买次数,新用户只消费了一次,老用户消费了两次及以上。
(total_df.groupby(by='user_id')['day'].count() == 1).value_counts()
'''
True     29919  # 新用户
False       25  # 老用户
Name: day, dtype: int64
'''

方式2
考虑购买时间,如果用户的消费时间只有一条,则视为新用户,否则视为老用户。
获取用户消费时间的最大值和最小值,并判断这两个时间是否相等。相等则视为新用户,否则视为老用户。

groupby + agg
方法agg是对分组后的数据做进一步聚合操作。

max_min_day_dt = total_df.groupby(by='user_id')['day'].agg(['min', 'max'])
max_min_day_dt.head()
'''
 		min 	max
user_id 		
2356 	2013-05-11 	2013-05-11
2757 	2013-04-10 	2013-04-10
3942 	2013-07-14 	2013-07-14
4468 	2013-08-15 	2013-08-15
7164 	2014-11-11 	2014-11-11
'''
(max_min_day_dt['min'] == max_min_day_dt['max']).value_counts()
'''
True     29920
False       24
dtype: int64
'''
  1. 添加新列,显示购买年份-月份。
total_df['month'] = total_df['day'].astype('datetime64[M]')
total_df['month'].head()
'''
0   2014-09-01
1   2013-10-01
2   2013-10-01
3   2014-10-01
4   2014-11-01
Name: month, dtype: datetime64[ns]
'''
  1. 查看每个月的商品销量情况,绘制线形图。
import matplotlib.pyplot as plt
%matplotlib inline 

sales_per_month_df = total_df.groupby(by='month')['buy_mount'].sum()

plt.plot(sales_per_month_df)
# plt.plot(sales_per_month_df.index, sales_per_month_df.values)

plt.xlabel('Month')
plt.ylabel('Sales')
plt.title('Sales per month')

plt.xticks(rotation=30)

在这里插入图片描述

  1. 添加两个新列,分别显示购买的年和购买的月。
total_df['year_num'] = total_df['day'].dt.year
total_df['month_num'] = total_df['day'].dt.month
  1. 查看2012,2013,2014年每个月的销量情况,绘制线形图。

准备数据
方式1

sales12_df = total_df.loc[total_df['year_num'] == 2012]
sales12_per_month_series = sales12_df.groupby(by='month_num')['buy_mount'].sum()
sales13_df = total_df.loc[total_df['year_num'] == 2013]
sales13_per_month_series = sales13_df.groupby(by='month_num')['buy_mount'].sum()
sales14_df = total_df.loc[total_df['year_num'] == 2014]
sales14_per_month_series = sales14_df.groupby(by='month_num')['buy_mount'].sum()

方式2

sales_per_month_series = total_df.groupby(by=['year_num','month_num'])['buy_mount'].sum()
sales12_per_month_series = sales_per_month_series[2012]
sales13_per_month_series = sales_per_month_series[2013]
sales14_per_month_series = sales_per_month_series[2014]
plt.plot(sales12_per_month_series, label='2012')
plt.plot(sales13_per_month_series, label='2013')
plt.plot(sales14_per_month_series, label='2014')
plt.legend()
plt.xlabel('Month')
plt.ylabel('Sales')
plt.title('Sales per month')

在这里插入图片描述

1.3.3.3 针对性分析

从上图可以看出,2012年至2014年的5月,9月和11月都出现高峰凸起,整体呈现上涨趋势。

  1. 添加新列,显示购买的日期。
total_df['day_num'] = total_df['day'].dt.day
  1. 查看每年的5月,9月和11月中每天的销量情况。
# 5月
# 2012年没有5月的数据
sales13_05_series = total_df.query('month == "2013-05-01"')
sales14_05_series = total_df.query('month == "2014-05-01"')

sales13_05_sum_series = sales13_05_series.groupby(by='day_num')['buy_mount'].sum()
sales14_05_sum_series = sales14_05_series.groupby(by='day_num')['buy_mount'].sum()

plt.plot(sales13_05_sum_series, label='2013-05')
plt.plot(sales14_05_sum_series, label='2014-05')
plt.legend()
plt.xlabel('Day')
plt.ylabel('Sales')
plt.title('Sales per day')

在这里插入图片描述

# 9月
sales12_09_series = total_df.query('month == "2012-09-01"')
sales13_09_series = total_df.query('month == "2013-09-01"')
sales14_09_series = total_df.query('month == "2014-09-01"')

sales12_09_sum_series = sales12_09_series.groupby(by='day_num')['buy_mount'].sum()
sales13_09_sum_series = sales13_09_series.groupby(by='day_num')['buy_mount'].sum()
sales14_09_sum_series = sales14_09_series.groupby(by='day_num')['buy_mount'].sum()

plt.plot(sales12_09_sum_series, label='2012-09')
plt.plot(sales13_09_sum_series, label='2013-09')
plt.plot(sales14_09_sum_series, label='2014-09')
plt.legend()
plt.xlabel('Day')
plt.ylabel('Sales')
plt.title('Sales per day')

在这里插入图片描述
在这里插入图片描述

# 11月
sales12_11_series = total_df.query('month == "2012-11-01"')
sales13_11_series = total_df.query('month == "2013-11-01"')
sales14_11_series = total_df.query('month == "2014-11-01"')

sales12_11_sum_series = sales12_11_series.groupby(by='day_num')['buy_mount'].sum()
sales13_11_sum_series = sales13_11_series.groupby(by='day_num')['buy_mount'].sum()
sales14_11_sum_series = sales14_11_series.groupby(by='day_num')['buy_mount'].sum()

plt.plot(sales12_11_sum_series, label='2012-11')
plt.plot(sales13_11_sum_series, label='2013-11')
# plt.plot(sales14_11_sum_series, label='2014-11')
plt.legend()
plt.xlabel('Day')
plt.ylabel('Sales')
plt.title('Sales per day')

在这里插入图片描述
在这里插入图片描述

  1. 分析商品的一级分类销量情况,绘制柱状图。
cat1_sales_series = total_df.groupby(by='cat1')['buy_mount'].sum()

cat1_sales_series.index
# Int64Index([28, 38, 50008168, 50014815, 50022520, 122650008], dtype='int64', name='cat1')
cat1_sales_series.index.astype('str')
# Index(['28', '38', '50008168', '50014815', '50022520', '122650008'], dtype='object', name='cat1')
plt.bar(cat1_sales_series.index.astype('str'), cat1_sales_series.values)
plt.xticks(rotation=30)

在这里插入图片描述

  1. 分析商品的一级分类与购买用户数量之间的关系,绘制柱状图。
    注意,存在同一用户多次购买的情况。

如果不考虑同一用户多次购买的情况,对商品一级分类进行分组后,直接统计每个用户出现的次数(count)。如果某个一级分类商品被某位用户购买了多次,则会被视为多个用户购买了该一级分类商品,导致购买该一级分类商品的用户数量偏高。

# 不考虑同一用户多次购买的情况。
# 
total_df.groupby(by='cat1')['user_id'].count()
'''
cat1
28            6963
38            1203
50008168     12494
50014815      4834
50022520      2367
122650008     2110
Name: user_id, dtype: int64
'''

考虑到同一用户多次购买的情况,需要对分组后的数据根据用户进行去重处理,再统计每个用户出现的次数,可以直接使用函数nunique。

# 考虑到同一用户多次购买的情况。
total_df.groupby(by='cat1')['user_id'].nunique()
'''
cat1
28            6958
38            1201
50008168     12484
50014815      4833
50022520      2367
122650008     2110
Name: user_id, dtype: int64
'''

因此需要考虑同一用户多次购买的情况。

cat1_user_count_df = total_df.groupby(by='cat1')['user_id'].nunique()
plt.bar(cat1_user_count_df.index.astype('str'), cat1_user_count_df.values)

在这里插入图片描述

  • 3
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值