# %%--- [python] cell-f74e05782eef # properties: # run_on_load: true # top_hidden: true # ---%% print("开始初始化数据分析和可视化的运行环境,请稍候……") import micropip await micropip.install("/pypi/openpyxl-3.1.5-py2.py3-none-any.whl") await micropip.install("/pypi/pyfonts-0.0.2-py3-none-any.whl") import pandas as pd import pyodide from pyfonts import load_font # 文件的URL file_url = '/assets/fonts/NotoSansSC-Regular.ttf' # 请将此URL替换为实际文件的URL # 本地保存路径 local_file_path = '/NotoSansSC-Regular.ttf' # 下载文件并保存到本地 try: response = await pyodide.http.pyfetch(file_url) # Return the response body as a bytes object image_data = await response.bytes() with open(local_file_path, 'wb') as f: f.write(image_data) print(f"中文字体已成功下载并保存为: {local_file_path}") except Exception as e: print(f"下载文件时出错: {e}") font = load_font(font_path="/NotoSansSC-Regular.ttf") print("数据分析和可视化的运行环境已经就绪。可以进行第1步了。") # %% [markdown] cell-5e351e7966a3 ## 🕐请从本地上传三个用电商记插件采集的新版淘宝、拼多多、京东搜索结果(含综合排序和销量排序)的Excel文件。[下载示例](https://www.dianshangji.cn/u/user5344/cfiles/browse/index?fid=3) # %%--- [html] cell-a5b79fdf3c10 # properties: # run_on_load: true # ---%% 请上传三个Excel文件:<input class="btn btn-primary" type="file" id="fileInput" multiple /> # %%--- [javascript] cell-d28877a258f5 # properties: # run_on_load: true # ---%% const fileInput = document.getElementById('fileInput'); const files = fileInput.files; if (files.length !== 3) { alert("Please select exactly three files: one for 淘宝, one for 拼多多, and one for 京东."); return; } // 先创建一个文件名到对应保存文件名的映射 const fileMapping = { '淘宝': '/taobao.xlsx', '拼多多': '/pdd.xlsx', '京东': '/jd.xlsx' }; // 遍历用户上传的所有文件 for (let file of files) { const fileName = file.name.toLowerCase(); // 判断文件名包含的关键词,并根据关键词确定保存文件的名称 let pyodideFileName = null; for (let key in fileMapping) { if (fileName.includes(key.toLowerCase())) { pyodideFileName = fileMapping[key]; break; } } // 如果文件名不符合要求 if (!pyodideFileName) { alert("Each file must be named with one of these keywords: '淘宝', '拼多多', or '京东'."); return; } // 读取文件为 ArrayBuffer const arrayBuffer = await file.arrayBuffer(); // 将 ArrayBuffer 转换为 Uint8Array const uint8Array = new Uint8Array(arrayBuffer); // 写入文件到 Pyodide 文件系统 console.log(pyodideFileName, uint8Array.length + '字节'); pyodide.FS.writeFile(pyodideFileName, uint8Array); } # %% [markdown] cell-d4de1bcd39b2 ## 🕑数据清洗与预处理 在进行数据分析之前,首先需要对采集到的数据进行清洗和预处理。 # %% [python] cell-50bbd749f8a1 import pandas as pd import re print("开始读取内存中的Excel文件……") # 读取淘宝、拼多多和京东的数据 df_taobao = pd.read_excel('/taobao.xlsx', skiprows=2, usecols=['商品ID', '价格', '月销量'], sheet_name='综合') df_pdd = pd.read_excel('/pdd.xlsx', skiprows=2, usecols=['商品ID', '价格', '月销量'], sheet_name='综合') df_jd = pd.read_excel('/jd.xlsx', skiprows=2, usecols=['商品ID', '价格', '评价'], sheet_name='综合') # 打印前几行数据以确认读取正确 print("淘宝表前几行:") print(df_taobao.head()) print("拼多多表前几行:") print(df_pdd.head()) print("京东表前几行:") print(df_jd.head()) # 处理月销量字段的函数 def clean_month_sales(sales_str): if pd.isna(sales_str): return None sales_str = str(sales_str).strip() # 根据不同的格式估算月销量 if "本月行业热销" in sales_str: return 1000 elif "万+" in sales_str: match = re.search(r'(\d+)', sales_str) if match: return int(match.group(1)) * 10000 # 假设每万+表示的销量为数字乘以10000 elif "+人" in sales_str: match = re.search(r'(\d+)', sales_str) if match: return int(match.group(1)) # 假设+人后跟的是具体的销量数字 try: return int(sales_str) # 尝试将字符串转为整数 except ValueError: return None # 京东“评价”字段估算为“月销量” def estimate_jd_sales(reviews): if pd.isna(reviews): return None reviews = str(reviews).strip() # 处理 "100+" 形式 if "万+" in reviews: # 提取“万+”格式的数字(如“5万+”) match = re.search(r'(\d+)', reviews) if match: return int(match.group(1)) * 1000 # 假设每万条评价对应1000月销量 elif "+" in reviews: # 提取“+”形式的数字(如“100+”) match = re.search(r'(\d+)', reviews) if match: # 如果是 "100+",假设销量为100到200之间 return int(match.group(1)) * 1.5 # 假设是100+表示的实际销量在100到200之间(系数1.5) else: # 处理没有"+"的数字(如"96") try: return int(reviews) * 1 # 假设每1个评价对应1件月销量 except ValueError: return None return None # 拼多多销量估算的缩放因子 def scale_pdd_sales(df, scale_factor=0.1): """根据淘宝销量对拼多多销量进行缩放""" df['月销量'] = df['月销量'] * scale_factor return df # 处理数据的通用函数 def processdata(df, is_jd=False, is_pdd=False): # 如果是拼多多数据,使用缩放因子调整销量 if is_pdd: df = scale_pdd_sales(df) #print(df.head(5)) # 如果是京东数据,使用估算月销量的函数 if is_jd: df['月销量'] = df['评价'].apply(estimate_jd_sales) elif is_pdd: pass else: # 处理“月销量”字段 df['月销量'] = df['月销量'].apply(clean_month_sales) # 筛选出“价格”小于等于1000元的记录 df = df[df['价格'] <= 1000] print("筛选出“价格”小于等于1000元的记录") #print(df.head(5)) # 筛选出“月销量”大于等于0,小于等于10000的记录 df = df[df['月销量'] >= 0] df = df[df['月销量'] <= 10000] print("筛选出“月销量”小于等于10000的记录") #print(df.head(5)) # 检查商品ID是否有重复记录 if df['商品ID'].duplicated().any(): print("存在重复的商品ID记录,正在去除重复条目...") df = df.drop_duplicates(subset=['商品ID'], keep='first') else: print("没有重复的商品ID记录。") # 打印前5条记录以检查结果 print(df.head(5)) print("有效记录总数:", len(df)) return df # 处理淘宝、拼多多和京东的数据 df_taobao = processdata(df_taobao, is_jd=False, is_pdd=False) df_pdd = processdata(df_pdd, is_jd=False, is_pdd=True) df_jd = processdata(df_jd, is_jd=True, is_pdd=False) print("数据已处理。") # %% [markdown] cell-ff91033e7acc ## 🕒价格区间直方图 # %% [python] cell-70f67d1cde93 import matplotlib.pyplot as plt await micropip.install("seaborn") import seaborn as sns def drawbarchart_price(name, df): # 假设 df 已经是一个包含商品ID、价格和月销量字段的 DataFrame # 选择“价格”字段来绘制价格分布图 plt.figure(figsize=(10, 6)) # 使用 seaborn 绘制价格的分布图 sns.histplot(df['价格'], kde=True, bins=30, color='blue') # 添加标题和标签 plt.title(name + '商品价格分布图', fontsize=16, font=font) plt.xlabel('价格', fontsize=12, font=font) plt.ylabel('频次', fontsize=12, font=font) # 显示图形 plt.show() # 绘制综合排序搜索数据的价格区间直方图 drawbarchart_price('淘宝综合价格分布', df_taobao) drawbarchart_price('拼多多综合价格分布', df_pdd) drawbarchart_price('京东综合价格分布', df_jd) # %%--- [markdown] cell-983a4edf8ee8 # properties: # top_hidden: true # ---%% ### 1. 导入必要的库 ``` import matplotlib.pyplot as plt await micropip.install("seaborn") import seaborn as sns ``` * `matplotlib.pyplot`: 用于绘制基本的图形,如线图、散点图、直方图等。它提供了很多自定义选项来控制图形的外观。 * `seaborn`: 基于`matplotlib`的一个高级可视化库,提供了更漂亮和更方便的绘图功能。`seaborn`与`matplotlib`兼容,并且能够创建复杂的统计图表。下面附录中详细讲解如何在交互式文档中安装seaborn库。 ### 2. 设置图表的大小 ``` plt.figure(figsize=(10, 6)) ``` * `plt.figure(figsize=(10, 6))`:指定图表的尺寸。`figsize`的参数是一个元组,表示图形的宽度和高度(单位是英寸)。例如,`figsize=(10, 6)`意味着图形的宽度是10英寸,高度是6英寸。 ### 3. 绘制价格分布图 ``` sns.histplot(df['价格'], kde=True, bins=30, color='blue') ``` 这个是`seaborn`库中的核心绘图函数之一——`histplot()`。它专门用于绘制直方图,提供了比`matplotlib`更高级的功能和更简洁的语法。 #### 解释每个参数: * `df['价格']`: * 这是我们数据框`df`中的`价格`字段。`seaborn.histplot()`需要一个数值型数据(例如,价格数据)来绘制直方图。 * `kde=True`: * `kde`表示“Kernel Density Estimate”(核密度估计),它是通过平滑曲线显示数据的分布。 * 核密度估计(KDE)是一种通过平滑数据点来估算连续变量分布的技术。它生成的是一个平滑的曲线,用来展示数据的整体分布趋势,而不是像直方图那样显示离散的条形。 * `kde=True`启用核密度估计,默认情况下它绘制的是与直方图重叠的平滑曲线。 * 如果你只想显示直方图,而不想显示KDE平滑曲线,可以设置`kde=False`。 * `bins=30`: * `bins`参数控制直方图中分箱(或区间)的数量。每个箱子对应一个区间,数据根据价格的值被分配到这些区间中。 * `bins=30`表示将价格范围分成30个区间。你可以调整这个参数来使直方图的分辨率更高或更低。 * 通常,`bins`的值会根据数据的大小、分布等进行调整。较小的`bins`可能会导致数据过于粗略,而较大的`bins`可能会过于细致。 * `color='blue'`: * `color`指定直方图的颜色。这里选择的是`blue`(蓝色)。你可以根据需要选择其他颜色,例如 `'red'`, `'green'` 或者使用颜色代码(如`#FF5733`)。 ### 4. 设置图表的标题和标签 ``` plt.title('商品价格分布图', fontsize=16) plt.xlabel('价格', fontsize=12) plt.ylabel('频次', fontsize=12) ``` * `plt.title('商品价格分布图', fontsize=16)`: 设置图表的标题,`fontsize=16`设置字体的大小为16。 * `plt.xlabel('价格', fontsize=12)`: 设置X轴的标签为“价格”,字体大小为12。 * `plt.ylabel('频次', fontsize=12)`: 设置Y轴的标签为“频次”,字体大小为12。 这些标签和标题使得图表更易于理解和呈现,尤其是当你展示给其他人时,它们有助于说明图表的含义。 ### 5. 显示图形 ``` plt.show() ``` * `plt.show()`:这个命令用于显示当前图形。它是`matplotlib`的标准方法,启动后会弹出图形窗口或将图形嵌入到Jupyter Notebook等环境中。 ### 总结: 这段代码的作用是生成一个显示商品价格分布的直方图,同时叠加一个平滑的KDE曲线(用于展示价格的分布趋势),并且设置了图表的标题、轴标签和图形大小。通过调整`bins`、`kde`等参数,你可以控制图表的细节和外观。 ### `seaborn.histplot()`常用参数: * `data`: 输入的数据,可以是一个DataFrame或Series。 * `kde`: 布尔值,是否启用KDE平滑曲线。默认`False`。 * `bins`: 控制直方图箱数目,数据的“分箱”数。也可以传递一个数组来自定义每个箱的边界。 * `color`: 设置条形的颜色。 * `hue`: 用于按类别进行颜色分组的字段(如果数据包含多个类别的话)。 * `stat`: 直方图的统计类型,默认是`'count'`,可以改为`'density'`表示频率密度。 如果你对`seaborn`或`matplotlib`有更多的疑问,欢迎继续提问! # %% [markdown] cell-10c8e96a2446 ## 🕓销量分布直方图 # %% [python] cell-f4ff7a08a942 def drawbarchart_sales(name, df): # 假设 df 已经是一个包含商品ID、价格和月销量字段的 DataFrame # 选择“价格”字段来绘制价格分布图 plt.figure(figsize=(10, 6)) # 使用 seaborn 绘制月销量的分布图 sns.histplot(df['月销量'], kde=True, bins=30, color='blue') # 添加标题和标签 plt.title(name + '商品销量分布图', fontsize=16, font=font) plt.xlabel('月销量', fontsize=12, font=font) plt.ylabel('频次', fontsize=12, font=font) # 显示图形 plt.show() # 绘制综合排序搜索数据的价格区间直方图 drawbarchart_sales('淘宝综合销量分布', df_taobao) drawbarchart_sales('拼多多综合销量分布', df_pdd) drawbarchart_sales('京东综合销量分布', df_jd)