據(jù)集:用 pandas 完成數(shù)據(jù)概覽與探索)
摘要拿到一份數(shù)據(jù)后不應該馬上開始清洗、分組或建模。第一步應先認識數(shù)據(jù)集有多少行、多少列、字段含義是什么、數(shù)據(jù)類型是否正確、缺失值分布如何、數(shù)值范圍是否異常、分類字段有哪些取值。本文圍繞 pandas 的數(shù)據(jù)概覽能力介紹head、info、describe、shape、dtypes、isna、value_counts、nunique等常用方法并通過一份訂單數(shù)據(jù)示例建立一套拿到數(shù)據(jù)后的探索檢查流程。一、背景與問題很多數(shù)據(jù)分析錯誤不是出現(xiàn)在復雜算法而是出現(xiàn)在最開始的數(shù)據(jù)理解階段日期字段被當成字符串處理。金額字段混入了空值、字符或異常負數(shù)。分類字段存在大小寫、空格和別名問題。主鍵并不唯一導致合并后數(shù)據(jù)量膨脹。缺失值集中在某些業(yè)務狀態(tài)中被誤認為隨機缺失。統(tǒng)計指標直接基于臟數(shù)據(jù)計算導致結論偏差。因此數(shù)據(jù)分析的第一步不是“算結果”而是回答幾個基礎問題這份數(shù)據(jù)有多大 每一列是什么含義 類型是否符合業(yè)務預期 有沒有缺失、重復和異常 關鍵字段的分布是否合理 是否可以支撐后續(xù)分析目標數(shù)據(jù)概覽就是在正式處理前建立對數(shù)據(jù)的第一層認知。二、核心概念1. 數(shù)據(jù)規(guī)模數(shù)據(jù)規(guī)模包括行數(shù)、列數(shù)、內存占用和字段數(shù)量。pandas 中常用方法作用df.shape查看行數(shù)和列數(shù)df.columns查看列名df.info()查看非空數(shù)量、類型和內存df.memory_usage()查看內存占用規(guī)模決定了后續(xù)處理方式。幾千行數(shù)據(jù)可以直接交互式分析幾千萬行數(shù)據(jù)則需要分塊、數(shù)據(jù)庫或更高性能工具。2. 字段類型字段類型決定能否進行正確計算金額和數(shù)量應是數(shù)值類型。日期應轉換為日期時間類型。狀態(tài)、地區(qū)、渠道適合作為分類字段。ID 字段通常應作為字符串處理而不是數(shù)值。ID 如果被當作數(shù)字可能丟失前導零例如訂單號000123變成123。3. 缺失值缺失值并不一定是錯誤。它可能表示業(yè)務上尚未發(fā)生。數(shù)據(jù)采集失敗。用戶未填寫。某些類型的記錄沒有該字段。系統(tǒng)遷移導致歷史數(shù)據(jù)不完整。處理缺失值前必須先理解缺失原因。4. 分布與異常數(shù)據(jù)分布幫助判斷字段是否合理。例如金額是否出現(xiàn)負數(shù)。年齡是否超過合理范圍。狀態(tài)字段是否出現(xiàn)未知值。日期是否超出分析窗口。某個渠道是否占比異常高。探索階段不一定立即修復問題但要記錄所有可疑點。三、工作原理1. 數(shù)據(jù)探索流程一套通用流程如下讀取數(shù)據(jù) → 查看樣例行 → 檢查規(guī)模和列名 → 檢查數(shù)據(jù)類型 → 檢查缺失值 → 檢查重復值 → 檢查數(shù)值分布 → 檢查分類字段取值 → 記錄數(shù)據(jù)問題探索流程的目標不是把所有問題一次性解決而是形成數(shù)據(jù)畫像。2. 樣例行的價值head()和tail()可以快速觀察數(shù)據(jù)格式但不要只看前幾行就下結論。很多數(shù)據(jù)文件前幾行可能是特殊樣本例如測試數(shù)據(jù)、歷史數(shù)據(jù)或導出說明。可以隨機抽樣查看df.sample(5,random_state42)隨機樣本更容易暴露字段格式不一致的問題。3. 統(tǒng)計描述的邊界describe()對數(shù)值列非常有用但它只能提供基礎統(tǒng)計。平均值、最大值和最小值不能替代業(yè)務判斷。例如訂單金額最大值很大可能是大客戶訂單也可能是金額單位錯誤。4. 探索結果應可復用數(shù)據(jù)探索不應只停留在 Notebook 輸出中。可以將關鍵檢查封裝為函數(shù)形成每次讀取數(shù)據(jù)后的固定檢查流程。四、實戰(zhàn)示例1. 準備示例數(shù)據(jù)frompathlibimportPathimportpandasaspd data_dirPath(data)data_dir.mkdir(exist_okTrue)orderspd.DataFrame({order_id:[A001,A002,A003,A004,A004,A006],customer:[Alice,Bob,Carol,David,David,None],region:[華東,華南,華東,華北,華北,華東 ],amount:[1200.0,800.0,1560.0,-20.0,-20.0,None],status:[paid,pending,paid,cancelled,cancelled,Paid],order_date:[2026-09-01,2026-09-02,2026-09-03,2026-09-04,2026-09-04,bad-date,],})orders.to_csv(data_dir/orders.csv,indexFalse,encodingutf-8-sig)這份數(shù)據(jù)故意包含重復訂單、缺失客戶、負金額、狀態(tài)大小寫不一致、地區(qū)空格和錯誤日期。2. 讀取數(shù)據(jù)并查看樣例importpandasaspd dfpd.read_csv(data/orders.csv)print(df.head())print(df.tail())print(df.sample(3,random_state42))樣例查看主要用于確認列名、字段內容和明顯格式問題。3. 查看規(guī)模和字段print(shape:,df.shape)print(columns:,df.columns.tolist())print(df.info())info()中的非空數(shù)量可以快速判斷哪些列存在缺失。對象類型列需要繼續(xù)判斷是字符串、混合類型還是日期未轉換。4. 檢查數(shù)據(jù)類型print(df.dtypes)df[amount]pd.to_numeric(df[amount],errorscoerce)df[order_date]pd.to_datetime(df[order_date],errorscoerce)print(df.dtypes)轉換后應重新檢查缺失值因為無法解析的數(shù)據(jù)會被轉換為缺失。5. 缺失值分析missing_countdf.isna().sum()missing_ratedf.isna().mean().sort_values(ascendingFalse)print(missing_count)print(missing_rate)缺失率高的字段不一定要刪除先判斷它是否對當前分析目標關鍵。6. 重復值檢查print(duplicated rows:,df.duplicated().sum())print(duplicated order_id:,df[order_id].duplicated().sum())print(df.loc[df[order_id].duplicated(keepFalse)])整行重復和業(yè)務主鍵重復是兩類不同問題。主鍵重復可能意味著重復導出、拆單、退款記錄或數(shù)據(jù)錯誤。7. 數(shù)值字段概覽print(df[amount].describe())print(df.loc[df[amount]0,[order_id,amount,status]])負金額可能是退款也可能是錯誤錄入。探索階段應把它標記出來后續(xù)根據(jù)業(yè)務規(guī)則處理。8. 分類字段分布print(df[status].value_counts(dropnaFalse))print(df[region].value_counts(dropnaFalse))狀態(tài)字段中paid和Paid可能表示同一個含義地區(qū)字段中的華東和華東也可能因為空格被當成不同值。9. 字符串標準化預覽previewdf.copy()preview[status_clean]preview[status].str.strip().str.lower()preview[region_clean]preview[region].str.strip()print(preview[status_clean].value_counts(dropnaFalse))print(preview[region_clean].value_counts(dropnaFalse))先做預覽不急著覆蓋原字段。確認規(guī)則正確后再進入正式清洗階段。10. 封裝探索函數(shù)defprofile_dataframe(frame:pd.DataFrame)-dict:return{shape:frame.shape,columns:frame.columns.tolist(),dtypes:frame.dtypes.astype(str).to_dict(),missing_count:frame.isna().sum().to_dict(),missing_rate:frame.isna().mean().round(4).to_dict(),duplicated_rows:int(frame.duplicated().sum()),}profileprofile_dataframe(df)print(profile)封裝后可以對不同數(shù)據(jù)文件重復使用也可以輸出為 JSON 或 Markdown 報告。11. 輸出數(shù)據(jù)概覽報告frompathlibimportPath output_dirPath(output)output_dir.mkdir(exist_okTrue)summarypd.DataFrame({dtype:df.dtypes.astype(str),missing_count:df.isna().sum(),missing_rate:df.isna().mean(),unique_count:df.nunique(dropnaTrue),})summary.to_csv(output_dir/data_profile.csv,encodingutf-8-sig)print(summary)這種字段級報告適合放進數(shù)據(jù)交付流程用于和業(yè)務同學確認字段質量。五、常見問題與實踐建議1. 為什么不能只看head()前幾行可能恰好很干凈不能代表整體。建議結合sample()、缺失值統(tǒng)計、分類分布和數(shù)值描述一起判斷。2.describe()是否能發(fā)現(xiàn)所有異常不能。它只能幫助發(fā)現(xiàn)明顯的數(shù)值極端值。分類值拼寫錯誤、日期解析失敗、主鍵重復、業(yè)務狀態(tài)非法需要單獨檢查。3. 缺失值是否應該全部填 0不應該。0 是一個有意義的數(shù)值缺失表示未知或不存在。把缺失值填 0 可能改變統(tǒng)計結果。應根據(jù)字段語義決定填充、刪除、保留或單獨標記。4. 為什么 ID 字段建議讀成字符串ID 可能包含前導零、字母、連接符或超長數(shù)字。讀成數(shù)值可能導致格式丟失或精度問題。訂單號、手機號、身份證號等通常都應該按字符串處理。5. 探索階段要不要直接修改數(shù)據(jù)建議先生成問題清單和預覽結果再進入正式清洗。探索和清洗分開可以減少誤修改也便于復盤每條規(guī)則的原因。六、進階思考1. 建立數(shù)據(jù)字典數(shù)據(jù)字典至少包含字段內容字段名數(shù)據(jù)文件中的列名中文含義字段業(yè)務解釋數(shù)據(jù)類型字符串、數(shù)值、日期等是否必填是否允許缺失取值范圍合法值或范圍示例典型樣例沒有數(shù)據(jù)字典時分析人員容易依靠猜測解釋字段。2. 用規(guī)則沉淀數(shù)據(jù)質量檢查探索階段發(fā)現(xiàn)的問題可以逐步變成數(shù)據(jù)質量規(guī)則order_id 不允許為空 order_id 在訂單主表中應唯一 amount 不允許為空 amount 允許為負數(shù)時必須對應退款狀態(tài) order_date 必須能解析為日期 status 必須屬于預定義枚舉這些規(guī)則后續(xù)可以用測試或數(shù)據(jù)質量工具自動執(zhí)行。3. 從探索到自動化手工探索適合新數(shù)據(jù)集。穩(wěn)定數(shù)據(jù)源應逐步自動化數(shù)據(jù)讀取 → 字段檢查 → 類型檢查 → 質量規(guī)則 → 輸出概覽報告 → 進入清洗流程這樣每次數(shù)據(jù)更新后都能快速發(fā)現(xiàn)異常。4. 注意樣本偏差如果數(shù)據(jù)來自抽樣、篩選或某個時間窗口概覽結果只代表當前樣本。報告中應記錄數(shù)據(jù)范圍、抽樣方式和數(shù)據(jù)來源。結論認識數(shù)據(jù)集是數(shù)據(jù)分析的第一步。通過 pandas 的shape、info、dtypes、isna、describe、value_counts、nunique等方法可以快速建立數(shù)據(jù)畫像發(fā)現(xiàn)缺失、重復、類型錯誤和異常分布。下一篇將進入數(shù)據(jù)讀取實踐系統(tǒng)講解 CSV、Excel 和數(shù)據(jù)庫數(shù)據(jù)如何讀入 pandas并處理編碼、日期、類型和大文件問題。參考資料pandas 官方文檔https://pandas.pydata.org/docs/pandasDataFrame.infohttps://pandas.pydata.org/docs/reference/api/pandas.DataFrame.info.htmlpandasDataFrame.describehttps://pandas.pydata.org/docs/reference/api/pandas.DataFrame.describe.html