项目:评估和清理英国电商公司销售数据
分析目标
此数据分析的目的是,根据市场销售数据,挖掘畅销产品,以便制定更有效的市场策略来提升营收。本实战项目的目的在于练习评估数据干净和整洁度,并且基于评估结果,对数据进行清洗,从而得到可供下一步分析的数据。
简介
原始数据集记录了一家英国在线零售公司在2010年12月1日至2011年12月9日期间的所有交易情况,涵盖了该公司在全球不同国家和地区的业务数据。该公司主要销售覆盖各个场景的礼品,包括但不限于生日礼品、结婚纪念品、圣诞礼品等等。该公司的客户群体主要包括批发商和个人消费者,其中批发商占据了相当大的比例。
数据每列的含义如下:
InvoiceNo
: 发票号码。6位数,作为交易的唯一标识符。如果这个代码以字母“c”开头,表示这笔交易被取消。StockCode
: 产品代码。5位数,作为产品的唯一标识符。Description
: 产品名称。Quantity
: 产品在交易中的数量。InvoiceDate
: 发票日期和时间。交易发生的日期和时间。UnitPrice
: 单价。价格单位为英镑(£)。CustomerID
: 客户编号。5位数,作为客户的唯一标识符。Country
: 国家名称。客户所居住的国家的名称。
读取数据
导入数据分析所需要的库,并通过Pandas的read_csv函数将原始数据文件"e_commerce.csv"里的数据内容解析为DataFrame,并赋值给变量original_data
import pandas as pd
original_data = pd.read_csv("e_commerce.csv")
评估数据
在这一部分将对上一部分建立的original_data这个DataFrame所包含的数据进行评估
评估主要从两个方面进行:结构和内容,即整齐度和干净度数据的结构性问题指不符合“每列是一个变量每行是一个观察值,每个单元格是一个值”这三个标准数据的内容性问题包括存在丢失数据,重复数据无效数据等
评估数据整齐度
original_data.sample(10)
从抽样的10行数据来看,数据符合"每列是一个变量,每行是一个观察值,每个单元格是一个值",具体来看每行是关于某商家的一次交易每列是交易相关的各个变量因此不存在结构性问题
评估数据干净度
origianl_data.info()
根据info信息可以看出一共有541909行数据,description和customerID非空缺数量是小于总行数的,所以这两个变量存在缺失值。并且invoiceData是指发票时间,则类型也应该是日期时间而不是字符串。customerID是用户编号,类型应该是字符串而不是浮点数
评估缺失数据
在了解Description存在缺失值后 根据条件提取出缺失观察值
original_data[original_data["Description"].isnull()]
有1454条交易数据缺失description变量值
从输出结果来看 这些缺失Description的交易数据,UnitPrice都为0.为了验证猜想,我们增加筛选条件看是否存在Description变量缺失且UnitPrice不为0的数据
original_data[(original_data["Description"].isnull()) & (original_data["UnitPrice"] != 0)]
筛选出来的结果数量为0条说明缺失Description值的数据,同时也不具备有效的UnitPrice值 Descriprion表示产品名称,UnitPrice表示产品单价,都是进行后续商品交易分析的重要变量,如果他们同时缺失则认为数据无法提供有效含义,因此后续可以被删除
CustomerID变量同样存在缺失值,因此也根据条件提取出缺失观察值
original_data[original_data["CustomerID"].isnull()]
CustomerID表示客户编号不是分析畅销商品的必要变量并且从输出结果来看 有些CustomerID缺失的交易数据仍然有效 因此保留此变量为空的观察值
评估重复数据
根据数据变量的含义来看虽然InvoiceNo,StockCode和CustomerID都是唯一标识符,但一次交易可能包含多件商品因此InvoiceNo可以存在重复 不同交易可以包含同一间商品因此StockCode可以存在重复 顾客可以进行多次交易或下单多个商品因此CustomerID也可以存在重复 所以无需评估重复数据
评估不一致数据
不一致数据可能存在于Country变量中我们需要查看是否存在多个不同值指代同一国家的情况
original_data["Country"].value_counts()
从Country变量值来看 ”USA“、“United States”均在表示美国,”United Kingdom“、“UK”、”U.K.“均在表示英国 因此应该在清洗步骤对这些值进行统一,只保留一个指代值
评估无效或错误数据
可以通过DataFrame的describe方法对数值统计信息进行快速了解
original_data.describe()
从输出结果来看Quantity和UnitPrice存在负数,会对后续数值分析产生影响 因此 我们先筛选出Quantity和UnitPrice数值为负数的观察值,进一步评估其含义
original_data[original_data["Quantity"] < 0]
original_data[(original_data["Quantity"] < 0) & (original_data["InvoiceNo"].str[0] !="C")]
original_data[(original_data["Quantity"] < 0) & (original_data["InvoiceNo"].str[0] !="C") & (original_data["UnitPrice"] !=0)]
根据输出结果猜想得到验证,当Quantity变量为负数的时候,观察值满足以下条件之一: 1.InvoiceNo以C开头,表示订单被取消 2.UnitPrice为0,说明单价为0英镑 这些交易数据均不是有效成交数据 不贡献销售不在后续的分析范围内,因此我们将在数据清理步骤,将Quantity为负数的观察值删除
筛选出UnitPrice为负数的观察值
original_data[original_data["UnitPrice"] < 0]
从输出结果来看UnitePrice为负数的观察值都是坏账调整 不属于商品交易数据 因此也在数据清洗步骤中也将其删除
清理数据
根据前面评估部分得到的结论 我们需要进行的数据清理包括
1.把InvoiceDate 变量的数据类型转换为日期时间
2.把CustomerID变量的数据类型转换为字符串
3.把description变量缺失的观察值删除
4.把country变量值”USA“替换为”United States“
5.把country变量值”UK“、”U.K.“替换为”United Kingdom“
6.把Quantity变量值为负数的观察值删除
7.把Unitprice变量值为负数的观察值删除
为了区分经过清理的数据和原始数据,我们创建新的变量cleand_data,让他为original_data复制出的副本 我们之后的清理步骤将被运用在cleand_data上
cleaned_data = original_data.copy()
cleaned_data.head()
1.把InvoiceDate 变量的数据类型转换为日期时间
cleaned_data["InvoiceDate"] = pd.to_datetime(cleaned_data["InvoiceDate"])
cleaned_data.head()
2.把CustomerID变量的数据类型转换为字符串
cleaned_data["CustomerID"] = cleaned_data["CustomerID"].astype(str)
cleaned_data["CustomerID"]
把CustomerID结尾的.0删除
cleaned_data["CustomerID"] = cleaned_data["CustomerID"].str.slice(0, -2)
cleaned_data["CustomerID"]
把Description变量缺失的观察值删除 并查看删除后该列空缺值个数和
cleaned_data.dropna(subset=["Description"], inplace=True)
cleaned_data["Description"].isnull().sum()
country变量值”USA“替换为”United States“,并检查替换后”USA“变量值个数
cleaned_data["Country"] = cleaned_data["Country"].replace({"USA": "United States"})
len(cleaned_data[cleaned_data["Country"]== "USA"])
把country变量值”UK“、”U.K.“替换为”United Kingdom“ ,并检查替换后“UK”,“U.K.”数量
cleaned_data["Country"] = cleaned_data["Country"].replace({"UK": "United Kingdom", "U.K.": "United Kingdom"} )
print(len(cleaned_data[cleaned_data["Country"]== "UK"]))
print(len(cleaned_data[cleaned_data["Country"]== "U.K"]))
把Quantity变量值为负数的观察值删除并检查替换后Quantity变量值为负数的个数
cleaned_data = cleaned_data[cleaned_data["Quantity"] >= 0]
len(cleaned_data[cleaned_data["Quantity"] < 0])
把UnitPrice变量值为负数的观察值删除并检查替换后UnitPrice变量值为负数的个数
cleaned_data = cleaned_data[cleaned_data["UnitPrice"] >= 0]
len(cleaned_data[cleaned_data["Quantity"] < 0])
保存清理后的数据
完成数据清理后把干净整齐的数据保存在新的文件里,文件名为e_commerce_cleaned.csv
cleaned_data.to_csv("e_commerce_cleaned.csv",index = False)
pd.read_csv("e_commerce_cleaned.csv").head()