
簡介面向數據分析初學者、消費電子市場研究者及智能手機行業從業者的智能手機價格可視化分析資料包聚焦品牌、型號、屏幕尺寸、處理器速度、內存大小、存儲容量、攝像頭規格、發布日期、價格等核心字段通過真實數據集揭示價格與配置、品牌之間的深層關聯。壓縮包內共3個文件csv格式原始數據集、ipynb交互式分析代碼和html結果展示頁整體僅1.07MB輕量易用既可直接用Excel、SPSS打開觀察數據也可在Jupyter Notebook中運行代碼復現分析全過程。代碼覆蓋數據清洗、數據整理、數據探索與可視化等關鍵環節能夠生成價格分布圖、品牌價格對比圖、性能與價格關系圖等直觀呈現影響智能手機定價的主要因素。目前已有189人學習/下載對于企業制定市場策略、確定產品定價以及消費者挑選高性價比機型都具有切實的數據參考價值。1. 智能手機價格數據集可視化分析配置數字和定價之間藏著哪些信息智能手機價格數據集是數據分析教學里很典型的一份表格數據每行是一部手機列是電池容量、內存、攝像頭像素、屏幕分辨率、重量等硬件參數最后一列把手機劃成 0 到 3 四個價格等級。很多人拿到它直接去做分類建模卻跳過了可視化分析這一步。恰恰是這一步能回答一個關鍵問題這個數據集里到底是什么在決定手機的價格。配置數字和最終定價之間不是一筆直賬——大電池不一定對應高價位雙卡和 4G 功能在低價機里反而出現得更頻繁。把表格用 pandas 讀進來再用 matplotlib 和 seaborn 畫幾張圖就能在建模前把特征與價格的關系摸清楚。這個案例適合學過 Python 基礎、想練數據清洗和可視化圖表的人跑通一遍之后換任何一張新的業務表格都能復制同樣的分析路徑。2. 數據準備讀取智能手機價格數據集并完成字段清洗拿到“數據集 代碼”這種組合的壓縮包解壓后通常會看到三個部分一個存放表格文件的 data 目錄、一兩個 .ipynb 或 .py 的代碼文件、以及數據說明文檔。我一般不會直接打開代碼跑而是先自己讀一遍數據。因為看別人寫的可視化代碼遠不如自己從 DataFrame 開始走一遍清洗流程能記住的字段含義更多后面調圖也更有底氣。2.1 解壓 .rar 后先理清數據集字段20 個硬件指標里哪些能用于定價分析公開渠道常見的智能手機價格數據集一般是 CSV 格式2000 行左右每行一部手機列名全部是英文縮寫。字段之間差異很大有的直接決定價格等級有的幾乎不影響。下面這張表列出了分析時要重點關注的字段便于后續看圖時能快速對應上硬件含義。字段名含義對定價分析的作用battery_power電池總容量mAh續航配置常用于判斷硬件成本ram運行內存MB與價格等級相關性通常最高的指標int_memory內置存儲GB存儲配置影響中高端定位px_height / px_width屏幕分辨率像素反映屏幕素質按兩個方向分別記錄mobile_wt手機重量g材質與機身體驗的間接信號n_coresCPU 核心數處理器檔位的一維近似fc / pc前置 / 主攝像頭像素影像能力營銷重點參數price_range價格等級 0 低 1 中 2 高 3 極高本次分析的目標變量讀取這類 CSV 時不需要做額外轉換pandas 能直接解析。但列名是縮寫字段單位也不統一所以讀進來第一件事不是畫圖而是把列看完、把缺失和類型確認掉。2.2 用 pandas 讀取 CSV 并檢查缺失、類型與重復值這里用 pandas 完成讀取encoding參數要按文件實際編碼調整常見的是utf-8或gbk。如果你的文件是 Excel 另存的 CSV列尾可能帶著不可見空格忽略這一步后面按列名篩選時會莫名報錯。import pandas as pd df pd.read_csv(train.csv, encodingutf-8) print(df.shape) print(df.info()) print(df.isnull().sum()) df.columns [c.strip().lower() for c in df.columns] df df.drop_duplicates().reset_index(dropTrue)shape能快速看出規模info()輸出每列的非空數量與數據類型isnull().sum()定位缺失位置。strip().lower()是為了統一列名格式避免Price_Range和price_range這種大小寫不一致導致后面取值失敗。drop_duplicates在這類公開數據集中通常不會刪掉多少行但重復樣本一旦混進相關性分析會讓某些特征與價格的相關系數被輕微放大。清洗后的數據就可以進入描述統計階段了。print(df.describe().T)describe()默認輸出均值、標準差、分位數轉置后按字段排列??催@一張表能快速發現兩個問題一是字段量綱差異巨大ram動輒上千 MB而n_cores只有個位數后面畫熱力圖前需要統一處理二是某些字段的標準差很小說明數據分布集中后續分組對比時它的區分度會偏弱。2.3 構造 price_label把 0-3 的價格等級映射成可讀標簽原數據里的price_range是離散字符0、1、2、3 四個檔位。直接用數字畫圖圖例上會出現“0 1 2 3”看圖的同事還得回憶哪個數字對應哪個檔位。我會在分析前生成一個可讀標簽列不改動原始列只在可視化時作為分組依據。df[price_label] df[price_range].map({ 0: 低價, 1: 中價, 2: 高價, 3: 極高 }) print(df.groupby(price_label)[price_range].count())map是 pandas 里做字典映射最直接的方式比replace少一層復制。分組計數用來確認四檔樣本量是否均衡樣本量太少的組在后續箱線圖里會缺乏說服力。如果某一檔只有幾十行后面分析它的均值差異時要特別標注“樣本量小結論僅供參考”。字段準備好之后就可以進入正式的圖表繪制環節。3. 單變量與多變量可視化價格分布與特征關系的圖表拆解python 數據分析與可視化到這個階段核心已經不再是 API 調用而是“每張圖想回答什么問題”。建議按這個順序推進先看目標變量分布建立對數據集的整體印象再看單個特征在不同價格等級下的差異最后才用散點和熱力圖找特征之間的關系。這樣每張可視化圖表的結論都能銜接到下一張圖的設計上。3.1 價格區間計數與電池容量直方圖先看分布再談關系第一張圖拆成兩個子圖左邊用countplot畫價格等級的樣本數量右邊用histplot畫電池容量分布。價格等級計數的意義在于確認類別平衡電池容量直方圖則是典型的單變量分布觀察看它是否符合常識預期比如是否集中在 1000-2000 mAh 附近。import matplotlib.pyplot as plt import seaborn as sns plt.rcParams[font.sans-serif] [Arial Unicode MS, SimHei] plt.rcParams[axes.unicode_minus] False fig, axes plt.subplots(1, 2, figsize(12, 4)) sns.countplot(datadf, xprice_range, axaxes[0]) axes[0].set_title(各價格等級樣本量) sns.histplot(datadf, xbattery_power, bins30, kdeTrue, axaxes[1]) axes[1].set_title(電池容量分布) plt.tight_layout() plt.show()bins30控制直方圖的分桶數量kdeTrue疊加一條核密度曲線用于觀察分布是單峰還是雙峰。tight_layout()防止兩個子圖的標題和坐標軸互相擠壓。這個數據集的電池容量分布通常比較均勻地落在 500-2000 mAh 區間沒有明顯的雙峰結構這說明單看電池容量無法把手機分成高價和低價兩撥后面需要用分組圖進一步觀察。3.2 箱線圖對比不同價格等級的 RAM 與內存等級差異是否肉眼可見箱線圖是可視化分析里對比分組差異最穩的圖形它同時展示中位數、四分位距和離群點。把 RAM 和內置存儲分別按price_range分組畫出來能直接看出高價組和低價組的中位數是否拉開了距離。fig, axes plt.subplots(1, 2, figsize(12, 4)) sns.boxplot(datadf, xprice_range, yram, axaxes[0]) axes[0].set_title(不同價格等級的 RAM 分布) sns.boxplot(datadf, xprice_range, yint_memory, axaxes[1]) axes[1].set_title(不同價格等級的內置存儲分布) plt.tight_layout() plt.show()看箱線圖的重點不是看有沒有重疊而是看中位數線的移動方向。如果price_range從 0 到 3 的過程中RAM 箱體的整體位置逐級抬升說明這個特征對價格等級有穩定的正向區分度。這個數據集里 RAM 通常是區分度最高的特征四個箱體幾乎不重疊而內置存儲的箱體之間交叉明顯區分能力弱很多。兩張圖放在一起自然引出下一個問題除了 RAM還有哪些特征與價格等級同步變化3.3 散點圖與相關性熱力圖尋找與價格等級同步變化的特征散點圖適合看兩個連續特征之間的聯合分布相關性熱力圖則把所有特征兩兩之間的關系壓縮進一張矩陣圖。這里把屏幕分辨率的兩個方向參數放在散點圖里用hue區分價格等級能直觀展示不同檔位在屏幕配置上的落點區域。fig, axes plt.subplots(1, 2, figsize(14, 5)) sns.scatterplot(datadf, xpx_height, ypx_width, hueprice_range, alpha0.5, axaxes[0]) axes[0].set_title(屏幕分辨率與價格等級) corr df.select_dtypes(includenumber).corr(numeric_onlyTrue) sns.heatmap(corr, cmapRdBu_r, center0, vmin-1, vmax1, squareTrue, cbar_kws{shrink: 0.8}, axaxes[1]) axes[1].set_title(特征相關性熱力圖) plt.tight_layout() plt.show()alpha0.5降低點的透明度密集區域的顏色深淺就能反映樣本密度避免點與點互相遮蓋。cmapRdBu_r讓正相關顯示為紅色、負相關顯示為藍色center0強制白色對應相關系數 0。select_dtypes(includenumber)自動排除對象型列防止price_label這種文本列混入計算。熱力圖里信息量最大的是最后一行或最后一列每個特征與price_range的相關系數。顏色越紅說明該特征與價格等級的正相關性越強。到這一步已經能初篩出三到四個關鍵特征下一步做分組量化驗證。4. 分組與相關性剖析找出影響智能手機定價的關鍵指標可視化圖表給人的是直觀印象但印象要靠數字驗證。這一章把上一步篩選出的特征拿來做分組聚合、相關系數排序和交叉表驗證回答一個明確的業務問題哪些硬件指標真正推高了價格等級。所有操作都基于 pandas 的聚合與統計函數不需要引入新的庫。4.1 按價格等級分組聚合均值差異量化關鍵特征分組聚合的意義在于把箱線圖里的“視覺差異”轉換成“數值差異”。對 RAM、電池容量、屏幕分辨率、重量等特征按price_range分組求均值看它們隨等級提升是否單調遞增。group_cols [ram, battery_power, px_height, mobile_wt, int_memory] grouped df.groupby(price_range)[group_cols].mean().round(1) print(grouped.T)groupby(price_range)把數據按目標變量分成四個子集.mean()計算各特征的均值.round(1)控制小數位.T轉置后特征變成行、價格等級變成列更容易逐行觀察遞增趨勢。表格中如果某個特征從低價到極高價的均值始終往上走它就是定價的核心驅動特征如果出現先升后降或來回波動說明它和價格等級不是線性關系。我一般在分析記錄里把單調遞增的特征打上標記后續做分類模型的特征篩選時優先保留。4.2 用相關系數排序定位 Top 指標并驗證 RAM 的主導地位分組均值看的是趨勢方向相關系數則給出一個可排序的強弱度量。計算每個數值特征與price_range的相關系數然后按絕對值從大到小排序是篩選特征最常用的做法。corr_target ( df.select_dtypes(includenumber) .corr(numeric_onlyTrue)[price_range] .drop(price_range) .sort_values(ascendingFalse) ) print(corr_target.head(10))corr(numeric_onlyTrue)計算整個數值矩陣取[price_range]這一列后用drop去掉自身再按降序排列。排序結果里排在第一位的基本可以確定是ram相關系數通常接近 0.9遠高于第二名。這里要提醒一個容易誤讀的點相關系數衡量的是線性相關強度相關系數高不代表因果關系。RAM 高和價格等級高同步出現原因可能是廠商在定價時把內存當作分檔標尺也可能只是這份數據生成時采用了這樣的規則??梢暬治鲭A段只需如實描述“RAM 是與價格等級同步性最強的單個指標”不需要下因果結論。4.3 交叉表驗證非數值特征藍牙、雙卡和 4G 是否真的影響定價這個數據集里除了連續數值列還有幾個取值為 0 或 1 的布爾類特征比如藍牙、雙卡、4G、Wifi。這類特征進不了普通的相關性矩陣但通過交叉表加normalize參數可以看各價格等級中“支持某項功能”的占比差異。cross pd.crosstab(df[price_range], df[four_g], normalizeindex) print(cross.round(3)) cross2 pd.crosstab(df[price_range], df[dual_sim], normalizeindex) print(cross2.round(3))pd.crosstab默認輸出頻數normalizeindex把每一行的數值歸一化成該價格等級內的比例.round(3)讓小數位更易讀。four_g這個特征在生成數據時使用邏輯回歸的方式做了關聯采樣因此在低價區間支持 4G 的比例更低。真實業務里4G、雙卡這類功能往往是入門機的標配反而可能出現在低價位段所以不要把這套結論直接遷移到真實手機銷售數據上。交叉表驗證的通用價值在于布爾特征也可以進入可視化分析流程并且能用與連續特征不同的展示方式獨立得出結論。5. 圖表落地與報告輸出把可視化結果變成可交付的分析產物分析做完代碼里畫了一堆圖真正要交付時卻經??ㄔ谌齻€細節中文亂碼、多圖排版擠在一起、報告發出去別人無法復現。這一章把最后一步補齊讓分析結果從 Jupyter Notebook 里走出來變成一份能直接發給同事的 HTML 文件。5.1 統一中文字體與圖表風格避免可視化圖表亂碼與默認樣式matplotlib 默認字體不支持中文直接設標題會出現方框。解決方法是統一設置字體族并確保axes.unicode_minus關閉否則負號在中文環境下會顯示成方塊。import matplotlib matplotlib.rcParams[font.sans-serif] [ Noto Sans CJK SC, SimHei, Arial Unicode MS ] matplotlib.rcParams[axes.unicode_minus] False提示Windows 上通常能直接命中SimHeimacOS 用Arial Unicode MSLinux 服務器上需要先確認是否安裝了Noto Sans CJK SC。字體設置應放在腳本開頭所有繪圖代碼之前。把字體配置和sns.set_style(whitegrid)一起放進去整套圖表的風格就統一了后續不用每張圖重復設置標題字體大小和網格樣式。5.2 用 subplots 把四張核心圖拼成一張結論大圖散落在多張圖里的結論拼接成一張大圖才有敘事感。這里把價格分布、RAM 箱線圖、分組均值折線、相關性 Top 特征四張圖組合到subplots里統一尺寸后導出 PNG。fig, axes plt.subplots(2, 2, figsize(14, 10)) sns.countplot(datadf, xprice_range, axaxes[0, 0]) sns.boxplot(datadf, xprice_range, yram, axaxes[0, 1]) sns.lineplot(datadf.groupby(price_range)[battery_power].mean(), markero, axaxes[1, 0]) sns.barplot(datadf, xprice_range, yram, estimatormedian, axaxes[1, 1]) fig.suptitle(智能手機價格數據集可視化分析結論圖, fontsize16) fig.tight_layout(rect[0, 0, 1, 0.96]) fig.savefig(phone_report.png, dpi150, bbox_inchestight)figsize(14, 10)保證導出后每個子圖都清晰可讀dpi150滿足打印和屏幕分享兩種場景bbox_inchestight去掉多余留白。tight_layout(rect...)給suptitle讓出頂部空間避免大標題被裁剪掉。拼圖的價值不在于展示更多圖表而是讓看圖的人按順序讀一遍樣本分布均勻、RAM 隨價格等級遞增、電池容量整體同步上升、RAM 中位數分級明顯四張圖形成一個完整論證鏈條。5.3 一鍵輸出 HTML 分析報告讓代碼跑完直接出交付物拿到結論圖之后最后一步是把圖片嵌入一個自包含的 HTML 文件用base64把 PNG 轉成內嵌數據。這樣交付的只有一個 .html 文件不依賴圖片路徑打開就能看。import base64 with open(phone_report.png, rb) as f: img_b64 base64.b64encode(f.read()).decode() summary_table df.groupby(price_label)[[ram, battery_power]].mean().round(1).to_html() html f htmlheadmeta charsetutf-8 title智能手機價格數據集可視化分析報告/title/head body h1價格等級特征差異/h1 {summary_table} h2核心結論圖/h2 img srcdata:image/png;base64,{img_b64} stylewidth:100%;max-width:960px; /body/html with open(report.html, w, encodingutf-8) as f: f.write(html)b64encode(f.read()).decode()把二進制圖片轉成字符串嵌入src的data:image/png;base64,...前綴瀏覽器就能直接渲染。to_html()把 pandas 的 DataFrame 轉成表格標簽中間不需要手寫一行 HTML 結構。這份report.html可以脫離 Jupyter 環境單獨打開也方便直接放進日報附件。本文還有配套的精品資源點擊獲取