據(jù)集CSV:10特征清洗分析與推薦實(shí)踐)
簡(jiǎn)介面向2021至2025年Steam游戲市場(chǎng)的公開(kāi)數(shù)據(jù)資源包含65,521款游戲條目適合游戲行業(yè)分析人員、市場(chǎng)研究者及對(duì)數(shù)字發(fā)行趨勢(shì)感興趣的學(xué)習(xí)者。數(shù)據(jù)來(lái)自官方Steam網(wǎng)頁(yè)API覆蓋appid、名稱、發(fā)行日期、美元價(jià)格、類型、類別、開(kāi)發(fā)者、出版商及用戶推薦數(shù)共10個(gè)字段可用于分析市場(chǎng)趨勢(shì)、類型熱度、定價(jià)策略與獨(dú)立游戲表現(xiàn)。資源包共2個(gè)文件以7z壓縮包形式提供內(nèi)含一個(gè)Python采集腳本與一個(gè)CSV數(shù)據(jù)文件整體大小約1.93MB。其中CSV為核心數(shù)據(jù)表Python腳本可用于數(shù)據(jù)更新或采集流程復(fù)現(xiàn)。已有349人瀏覽學(xué)習(xí)便于快速獲取結(jié)構(gòu)化數(shù)據(jù)進(jìn)行二次分析或可視化。該數(shù)據(jù)集時(shí)間跨度完整兼顧已發(fā)售作品與計(jì)劃于2025年發(fā)布的未來(lái)作品能為行業(yè)觀察與量化分析提供基礎(chǔ)支撐。1. 2021-2025 Steam游戲數(shù)據(jù)集10特征65k個(gè)獨(dú)立條目CSV想研究游戲市場(chǎng)從這張表開(kāi)始拿到這份 2021-2025 Steam游戲數(shù)據(jù)集10特征65k個(gè)獨(dú)立條目CSV最值得做的不是急著畫(huà)圖而是先想清楚一個(gè)問(wèn)題這 65k 條記錄能幫你驗(yàn)證什么假設(shè)Steam 游戲列表本身并不稀缺稀缺的是把時(shí)間跨度、定價(jià)、評(píng)價(jià)、類型、標(biāo)簽壓縮到一張表里讓你能快速回答“疫情后獨(dú)立游戲是不是更多了”“免費(fèi)游戲的評(píng)分是不是真的更分化”“2024 年哪些品類發(fā)行量在漲”這類問(wèn)題。它適合四類人想入門(mén)數(shù)據(jù)分析的新手、做推薦系統(tǒng)的算法工程師、寫(xiě) Steam 相關(guān)爬蟲(chóng)或應(yīng)用的后端開(kāi)發(fā)以及做游戲市場(chǎng)研究的從業(yè)者。CSV 格式意味著你不需要任何數(shù)據(jù)庫(kù)pandas 就能直接讀但在開(kāi)始之前先別把“特征數(shù)”當(dāng)成“列數(shù)”理解下面我會(huì)從一個(gè)最常用的 10 列結(jié)構(gòu)展開(kāi)講清楚。2. 先看清楚 10 個(gè)特征再動(dòng)手字段語(yǔ)義、讀取參數(shù)和第一眼檢查2.1 一份 Steam 游戲 CSV 常見(jiàn)的 10 個(gè)特征是什么我接觸過(guò)不少 Steam 游戲類 CSV列名很少完全一致但核心信息通常是同一批游戲唯一標(biāo)識(shí)、名稱、發(fā)布日期、價(jià)格、開(kāi)發(fā)者/發(fā)行商、類型、標(biāo)簽、好評(píng)數(shù)、差評(píng)數(shù)、好評(píng)率。把這些列湊齊正好是 10 個(gè)特征特征名類型說(shuō)明app_idint/strSteam 應(yīng)用唯一 ID去重和關(guān)聯(lián)外部數(shù)據(jù)的鑰匙namestr游戲名注意可能有重名和空格release_datestr/datetime發(fā)行日期常見(jiàn)格式為 YYYY-MM-DDpricefloat當(dāng)前價(jià)格美元免費(fèi)游戲常為 0developersstr開(kāi)發(fā)者多個(gè)用逗號(hào)或豎線分隔genresstr主類型如 Action、Indie、Strategytagsstr社區(qū)標(biāo)簽通常用豎線分隔數(shù)量較多positive_reviewsint好評(píng)數(shù)量negative_reviewsint差評(píng)數(shù)量positive_ratiofloat好評(píng)率取值 0~100注意單位是百分比還是 0~1前面幾列一眼就能看懂真正影響后續(xù)分析的是positive_ratio的單位和tags的分隔符。如果你直接拿positive_ratio去乘 100或者把tags當(dāng)成單個(gè)字符串去匹配“多人”或“單機(jī)”后面所有統(tǒng)計(jì)都會(huì)翻車。拿到 CSV 的第一件事不是訓(xùn)練模型而是用一個(gè)標(biāo)準(zhǔn)流程確認(rèn)字段類型和取值分布。2.2 用 pandas 讀取 CSVencoding 和 dtype 是兩個(gè)省內(nèi)存開(kāi)關(guān)讀取一張 65k 行、10 列的表文件本身可能只有幾 MB 到幾十 MB但如果你不做任何處理pandas 會(huì)默認(rèn)把每一列都讀成對(duì)象或 64 位整數(shù)內(nèi)存翻兩三倍很常見(jiàn)。我一般會(huì)在讀取時(shí)就指定dtype避免事后才發(fā)現(xiàn)app_id被讀成了 float。import pandas as pd df pd.read_csv( steam_games_2021_2025.csv, encodingutf-8, dtype{ app_id: int32, price: float32, positive_reviews: int32, negative_reviews: int32, positive_ratio: float32, }, parse_dates[release_date], low_memoryFalse, ) print(df.shape) print(df.head()) print(df.info(memory_usagedeep))這段代碼里最值得注意的兩個(gè)參數(shù)是dtype和parse_dates。dtype讓數(shù)字列用更小的整型和浮點(diǎn)型存儲(chǔ)65k 行看不出明顯差異但后面一旦要合并 Steam 爬蟲(chóng)或外部評(píng)分?jǐn)?shù)據(jù)這個(gè)習(xí)慣能省下幾十 MB。parse_dates會(huì)把發(fā)行日期在讀取階段就轉(zhuǎn)成datetime64避免你之后用pd.to_datetime再去遍歷一遍。low_memoryFalse是為了防止 pandas 在分塊讀取時(shí)因?yàn)榱蓄愋屯茢嗖灰恢露o出潛在類型警告。讀取完成后不要急著 head()先跑一下df.isna().sum()看空值列在哪些特征上。很多由爬蟲(chóng)生成的 CSV 會(huì)在tags、developers上留下空值這些空值不是簡(jiǎn)單的“沒(méi)有”可能是爬蟲(chóng)沒(méi)有抓取到也可能是獨(dú)立游戲確實(shí)沒(méi)有填寫(xiě)標(biāo)簽處理方式完全不同。2.3 從特征到業(yè)務(wù)問(wèn)題哪些列可以組合使用10 個(gè)特征不是 10 個(gè)獨(dú)立變量組合起來(lái)才能回答更具體的問(wèn)題。比如release_date加genres可以看類型發(fā)行量隨年份的變化price加positive_ratio可以看定價(jià)區(qū)間與口碑的關(guān)系tags加positive_reviews可以找出“EA 測(cè)試但評(píng)價(jià)不錯(cuò)”的小眾產(chǎn)品。我習(xí)慣在清洗之前先做一遍“假設(shè)映射”也就是把業(yè)務(wù)問(wèn)題拆成特征組合否則很可能會(huì)多洗掉不少有價(jià)值的數(shù)據(jù)。比如positive_ratio如果缺失不要立刻刪行而是看positive_reviews和negative_reviews是否存在存在的話完全可以用后者手工計(jì)算好評(píng)率。3. 數(shù)據(jù)清洗把 10 個(gè)特征變成可供模型使用的干凈寬表3.1 日期、價(jià)格、空值三個(gè)最先翻車的字段幾乎所有 Steam 類 CSV 都逃不過(guò)這三個(gè)坑日期格式不統(tǒng)一、價(jià)格字段混入 “Free to Play” 或 “免費(fèi)” 等文本、空值分布在多個(gè)列。直接dropna()會(huì)把 65k 刪到 30k屬于最粗暴的解法。我更傾向于按列清洗先讓每一列都能被正確解釋再?zèng)Q定是否刪除行。import pandas as pd # 日期不強(qiáng)制格式讓 pandas 自動(dòng)解析解析失敗的置為 NaT df[release_date] pd.to_datetime(df[release_date], errorscoerce) # 價(jià)格先統(tǒng)一轉(zhuǎn)成字符串處理再轉(zhuǎn)數(shù)值 df[price] df[price].astype(str).str.strip().str.lower() df.loc[df[price].str.contains(free, naFalse), price] 0 df[price] pd.to_numeric(df[price], errorscoerce) # 空值只對(duì)關(guān)鍵列刪除缺失 df df.dropna(subset[app_id, name, release_date]) print(df.shape) print(df[df[price].isna()][[name, price]].head())這段代碼的邏輯分三步走。第一步把release_date統(tǒng)一成 datetimeerrorscoerce會(huì)把類似 “2025-01-15” 和 “2025/1/15” 都解析掉但純年份或 “Coming Soon” 會(huì)變成NaT后續(xù)再單獨(dú)處理。第二步處理價(jià)格這里容易踩的細(xì)節(jié)是astype(str)之后整列變成字符串str.contains(free, naFalse)才能安全過(guò)濾空值最后再轉(zhuǎn)數(shù)值。第三步只對(duì)主鍵列刪除缺失價(jià)格缺失可以先保留后面用 0 或中位數(shù)填充。我在實(shí)際處理中會(huì)把解析失敗的日期單獨(dú)列出來(lái)看而不是直接刪掉。很多時(shí)候失敗信息里能看到 “TBA” 或 “2025” 這樣的短格式它們可以單獨(dú)歸為一類“即將發(fā)行”或“年份未知”不需要完全丟棄。3.2 好評(píng)率、發(fā)行年份、標(biāo)簽拆分的特征工程原始 10 個(gè)特征對(duì)機(jī)器學(xué)習(xí)來(lái)說(shuō)太原始了至少要構(gòu)造出年份、歸一化好評(píng)率、標(biāo)簽列表三個(gè)新變量。這里有一個(gè)經(jīng)驗(yàn)positive_ratio即使已經(jīng)給定我仍然會(huì)重算一遍因?yàn)樯贁?shù)行的positive_ratio可能是爬蟲(chóng)算錯(cuò)的用positive_reviews / (positive_reviews negative_reviews)校驗(yàn)一下更穩(wěn)妥。# 發(fā)行年份 df[year] df[release_date].dt.year # 好評(píng)率用好評(píng)數(shù)重新計(jì)算避免原字段單位不統(tǒng)一 review_total df[positive_reviews] df[negative_reviews] df[positive_ratio_calc] df[positive_reviews] / review_total.replace(0, pd.NA) df.loc[review_total 0, positive_ratio_calc] pd.NA # 標(biāo)簽拆分為列表方便后續(xù)做多標(biāo)簽分析 df[tags_list] df[tags].fillna().str.split(|) # 把拆分后的標(biāo)簽展開(kāi)成長(zhǎng)表 tags_expanded df[[app_id, tags_list]].explode(tags_list) tags_expanded tags_expanded.dropna(subset[tags_list]) print(df[[name, year, positive_ratio, positive_ratio_calc]].head()) print(tags_expanded.head())這里最值得關(guān)注的是explode這一步。它把一行包含多個(gè)標(biāo)簽的游戲拆成多行好處是后續(xù)做“哪個(gè)標(biāo)簽平均好評(píng)率最高”的聚合變得非常直接壞處是如果直接讓訓(xùn)練集爆炸會(huì)引入大量重復(fù)樣本。所以我在實(shí)際工程里通常會(huì)保留兩份數(shù)據(jù)一份是原始寬表df用于建模一份是長(zhǎng)表tags_expanded用于統(tǒng)計(jì)和標(biāo)簽特征。兩個(gè)表用app_id來(lái)做映射避免在長(zhǎng)表上反復(fù)展開(kāi)和合并。review_total.replace(0, pd.NA)也是一種常見(jiàn)防御寫(xiě)法沒(méi)有評(píng)論的游戲不應(yīng)被當(dāng)成 0% 好評(píng)而應(yīng)視為未知。后面填充時(shí)我會(huì)單獨(dú)把positive_ratio_calc填為一個(gè)中心值比如 0.6而不是 0。這個(gè)細(xì)節(jié)直接影響推薦系統(tǒng)里冷啟動(dòng)策略。3.3 清洗后的質(zhì)量校驗(yàn)為什么別直接用 groupby 出結(jié)論清洗后最常犯的錯(cuò)是直接df.groupby(year).size()然后開(kāi)始畫(huà)圖結(jié)果發(fā)現(xiàn)某一年數(shù)量異常。原因很可能是在release_date解析階段把很多無(wú)效值歸到了同一年或者存在重復(fù)下載導(dǎo)致的重復(fù)行。# 1. 檢查重復(fù)主鍵 dup_count df[app_id].duplicated().sum() print(fduplicated app_id: {dup_count}) # 2. 檢查年份分布是否合理 year_dist df[year].value_counts().sort_index() print(year_dist) # 3. 檢查價(jià)格是否有極端值 print(df[price].describe()) # 4. 清洗完成校驗(yàn)保存前確認(rèn)主鍵唯一 df df.drop_duplicates(subset[app_id], keepfirst) df.to_csv(steam_clean.csv, indexFalse)我一般在剔重前會(huì)先問(wèn)自己一句這個(gè)數(shù)據(jù)集是從單一 API 拿的還是多個(gè)爬蟲(chóng)拼的如果是多源合并重復(fù)不一定是同一款游戲可能是某個(gè) DLC 或測(cè)試版占了多個(gè)條目。此時(shí)app_id唯一不一定合理需要先看name是否完全相同。如果構(gòu)建推薦系統(tǒng)我會(huì)保留最全的那條記錄如果只做市場(chǎng)統(tǒng)計(jì)則應(yīng)該把重復(fù)項(xiàng)單獨(dú)標(biāo)記而不是默默刪掉。4. 用 10 個(gè)特征回答三個(gè)業(yè)務(wù)問(wèn)題趨勢(shì)、定價(jià)與口碑4.1 2021-2025 發(fā)行數(shù)量與類型遷移清洗完成后第一個(gè)值得驗(yàn)證的問(wèn)題是2021 到 2025 年Steam 游戲的發(fā)行量到底在漲還是跌如果把release_date拆成年份再疊加上genres分組看會(huì)發(fā)現(xiàn)“類型遷移”比總量更有意思某些年份動(dòng)作射擊類數(shù)量下滑模擬經(jīng)營(yíng)和生存類上升。這背后可能是市場(chǎng)偏好變化也可能是爬蟲(chóng)采集范圍變化所以在得出結(jié)論前要給構(gòu)圖留一個(gè)交叉驗(yàn)證步驟。import pandas as pd df pd.read_csv(steam_clean.csv, parse_dates[release_date]) df[year] df[release_date].dt.year # 按年份統(tǒng)計(jì)發(fā)行量 trend df.groupby(year).size().reset_index(namegame_count) # 按年份類型統(tǒng)計(jì) genre_trend df.dropna(subset[genres]).copy() genre_trend[main_genre] genre_trend[genres].str.split(,).str[0].str.strip() genre_trend genre_trend.groupby([year, main_genre]).size().reset_index(namecount) pivot genre_trend.pivot(indexyear, columnsmain_genre, valuescount).fillna(0) print(pivot.head(10))這段代碼里有一個(gè)手動(dòng)選主類型的動(dòng)作str.split(,).str[0]會(huì)把多重類型里的第一個(gè)當(dāng)作主類型因?yàn)樗罱咏螒虻暮诵姆诸?。這樣處理可以讓pivot后的表列數(shù)不會(huì)爆炸到幾十個(gè)。如果某些行g(shù)enres是空值dropna(subset[genres])會(huì)丟棄這部分但注意這會(huì)減少統(tǒng)計(jì)總量單獨(dú)畫(huà)個(gè)餅圖看缺失占比更穩(wěn)妥。4.2 定價(jià)策略免費(fèi)游戲、付費(fèi)區(qū)間與好評(píng)率的關(guān)系價(jià)格和口碑的關(guān)系在游戲行業(yè)里一直是熱門(mén)話題。免費(fèi)游戲因?yàn)榛A(chǔ)用戶量大好評(píng)率往往高于預(yù)期低價(jià)獨(dú)立游戲則容易陷入“好評(píng)但沒(méi)銷量”的困境。要驗(yàn)證這個(gè)先把價(jià)格分成幾個(gè)區(qū)間再看每個(gè)區(qū)間的好評(píng)率中位數(shù)效果比散點(diǎn)圖直觀得多。bins [-0.01, 0, 9.99, 19.99, 29.99, 59.99, float(inf)] labels [free, under_10, 10_20, 20_30, 30_60, above_60] df[price_range] pd.cut(df[price], binsbins, labelslabels, rightFalse) # 好評(píng)率中位數(shù)和游戲數(shù)量 price_group df.dropna(subset[positive_ratio_calc]) \ .groupby(price_range, observedFalse)[positive_ratio_calc] \ .agg([median, count]) print(price_group)pd.cut的rightFalse很關(guān)鍵它保證 9.99 被歸到 “under_10” 而不是 “10_20”。另外observedFalse是我們處理 category 類型時(shí)防止 pandas 3.0 警告的標(biāo)準(zhǔn)寫(xiě)法。如果你用過(guò)老版本 pandas這里可能會(huì)踩到 category 的坑下面一節(jié)會(huì)專門(mén)講。4.3 把結(jié)論沉淀成一張可以直接用的寬表分析完之后我一般會(huì)把聚合結(jié)果導(dǎo)出成一個(gè)更小的寬表用于后續(xù)可視化或前端展示而不是讓其他人直接操作 65k 行的原始表。summary df.groupby(year, as_indexFalse).agg( game_count(app_id, count), mean_price(price, mean), median_ratio(positive_ratio_calc, median), total_positive(positive_reviews, sum), ) summary.to_csv(steam_yearly_summary.csv, indexFalse) print(summary)as_indexFalse讓year保留為列而不是變成索引這樣導(dǎo)出 CSV 后其他人可直接導(dǎo)入 Excel 或做 BI 圖表不用再 reset_index。這張表已經(jīng)足夠回答經(jīng)常被問(wèn)的“這幾年 Steam 游戲整體是不是變貴了”這類問(wèn)題。5. 常見(jiàn)問(wèn)題與踩坑處理 Steam 游戲 CSV 時(shí)最常翻車的 5 個(gè)瞬間5.1 現(xiàn)象讀取 CSV 后 app_id 變成 float后面合并全部錯(cuò)位原因CSV 里有空行或爬蟲(chóng)把 app_id 寫(xiě)成了科學(xué)計(jì)數(shù)法pandas 自動(dòng)推斷列類型時(shí)把它當(dāng)成浮點(diǎn)型。此時(shí)df[app_id]里的值從amp55變成5.5e05最直接的后果就是 join 外部數(shù)據(jù)時(shí)能匹配上的一般不足 10%。解決讀取時(shí)強(qiáng)制指定dtype{app_id: str}并在讀取后檢查是否存在形如730.0的字符串。如果已發(fā)生用df[app_id] df[app_id].astype(str).str.replace(r\.0$, , regexTrue)清理。5.2 現(xiàn)象release_date 中混入 “2025.1.5” 和 “2025-01-05” 后pd.to_datetime 解析出現(xiàn)不同年月原因Steam 數(shù)據(jù)源存在多套格式部分抓取工具會(huì)把點(diǎn)號(hào)或下劃線當(dāng)成日期分隔符自動(dòng)解析會(huì)誤以為 “5” 是月份。解決不要信任自動(dòng)解析。我把release_date先轉(zhuǎn)成字符串用正則統(tǒng)一替換分隔符為-再指定format或使用errorscoerce配合后續(xù)手工校驗(yàn)。更穩(wěn)妥的是拿到數(shù)據(jù)時(shí)就先做一輪strftime標(biāo)準(zhǔn)化而不是等建模前再處理。5.3 現(xiàn)象CSV 里某列出現(xiàn)換行符read_csv 后行數(shù)比預(yù)期多幾百行原因游戲簡(jiǎn)介或 tags 字段里含有\(zhòng)n如果生成 CSV 時(shí)沒(méi)有套用 CSV 引號(hào)規(guī)則pandas 默認(rèn)按換行切分導(dǎo)致單行斷成多行。解決讀取時(shí)使用quotingcsv.QUOTE_ALL或至少enginepython。如果文件已經(jīng)損壞可以用csv模塊逐行恢復(fù)但更建議從源頭爬蟲(chóng)端修好寫(xiě)入時(shí)用csv.writer(row)并用quotechar不要手工用逗號(hào)拼接字段。5.4 現(xiàn)象清洗后只剩 3 萬(wàn)行數(shù)據(jù)量腰斬原因一次性dropna()把所有有缺失的列全部過(guò)濾開(kāi)發(fā)者、標(biāo)簽、好評(píng)率任一缺失都會(huì)刪掉整行。解決改變清洗順序先對(duì)主鍵列去重再對(duì)參與建模的核心列release_date、price做局部dropna其余缺失列用中位數(shù)、眾數(shù)或?qū)iT(mén)標(biāo)記填充。比如developers缺失可以填unknownpositive_ratio_calc缺失可以填 50 分位而不是丟數(shù)據(jù)。5.5 現(xiàn)象用外部 Steam 數(shù)據(jù)去補(bǔ) CSV 時(shí)按名稱匹配成功率不到一半原因同一游戲在不同來(lái)源中的名稱可能差一個(gè)空格、年份或副標(biāo)題比如 “Dota 2” 和 “Dota2” 表現(xiàn)不一致名稱匹配天然不可靠。解決不要直接用name作 key統(tǒng)一通過(guò)app_id關(guān)聯(lián)。如果外部接口沒(méi)有返回 ID先做一個(gè)歸一化函數(shù)轉(zhuǎn)小寫(xiě)、去空格、統(tǒng)一全半角再生成一個(gè)slug列用于模糊匹配。這么做之后匹配率會(huì)從 40% 提到 90% 以上。補(bǔ)充數(shù)據(jù)時(shí)還容易觸發(fā) Steam 側(cè)連接失敗或限流提示解決辦法是加隨機(jī)延時(shí)、按app_id升序遍歷、失敗自動(dòng)跳過(guò)而不是一次性并發(fā)請(qǐng)求。6. 繼續(xù)往前走用清洗后的 CSV 跑一個(gè)最小推薦并建立更新習(xí)慣6.1 基于類型和標(biāo)簽做內(nèi)容推薦的最小實(shí)現(xiàn)當(dāng)字段清洗到genres和tags_list都能干凈使用時(shí)最值得做的進(jìn)階嘗試是內(nèi)容推薦。對(duì) 65k 條游戲做近鄰搜索并不需要復(fù)雜的圖模型TF-IDF 加余弦相似度已經(jīng)能給出不錯(cuò)的效果而且代碼很短from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity df[_text] ( df[genres].fillna() df[tags].fillna().astype(str).str.replace(|, , regexFalse) ) vec TfidfVectorizer(min_df2, max_features5000) mat vec.fit_transform(df[_text]) sim cosine_similarity(mat) # 找一個(gè)具體游戲做演示 demo_idx df.index[df[name] Dota 2] if len(demo_idx) 0: top5 sim[demo_idx[0]].argsort()[::-1][1:6] print(df.iloc[top5][[name, genres, positive_ratio_calc]])min_df2表示出現(xiàn)次數(shù)低于 2 的標(biāo)簽直接忽略避免稀碎標(biāo)簽影響相似度max_features5000是控制詞表規(guī)模防止 65k 行 幾十萬(wàn)標(biāo)簽導(dǎo)致矩陣過(guò)大。如果你發(fā)現(xiàn)結(jié)果里全是類型相似的換皮游戲可以手動(dòng)調(diào)大min_df或給tags更大的權(quán)重。我在實(shí)際項(xiàng)目里還會(huì)把流行度和差評(píng)率作為后過(guò)濾條件避免推薦“極其相似但評(píng)價(jià)很差”的作品。6.2 新數(shù)據(jù)進(jìn)來(lái)之后怎么維護(hù)一年后再看這份 2021-2025 數(shù)據(jù)集里面可能已經(jīng)少了新上線的游戲。常見(jiàn)做法是寫(xiě)一個(gè)定時(shí)拉取腳本通過(guò) Steam 官方開(kāi)發(fā)者接口增量抓新增 app_id再把新數(shù)據(jù)concat到原表上進(jìn)行清洗和去重。new_df pd.read_csv(steam_latest_2026.csv) merged pd.concat([df, new_df], ignore_indexTrue) merged merged.drop_duplicates(subset[app_id], keeplast) merged.to_parquet(steam_games.parquet, indexFalse)這里我會(huì)刻意把清洗后的結(jié)果存成 Parquet 而不是繼續(xù)存 CSV因?yàn)?Parquet 支持類型、壓縮比高隨后的查詢速度更快。如果后續(xù)要接入上層的 Web 服務(wù)再多一步to_sql寫(xiě)入 SQLite 或 PostgreSQL 即可。數(shù)據(jù)庫(kù)導(dǎo)入 CSV 文件這個(gè)操作只有在數(shù)據(jù)量小、一次性分析時(shí)才建議直接使用一旦進(jìn)入持續(xù)更新階段還是讓程序?qū)憥?kù)更可控。以前我拿到一個(gè)新數(shù)據(jù)集總急著跑模型后來(lái)發(fā)現(xiàn)特征里的時(shí)間、價(jià)格、空值全在騙人?,F(xiàn)在我給自己定了一條規(guī)矩先畫(huà)分布、后寫(xiě) schema、再進(jìn)模型。這份 2021-2025 Steam 游戲數(shù)據(jù)集正好是練手的好目標(biāo)希望這些經(jīng)驗(yàn)?zāi)軒偷侥?。本文還有配套的精品資源點(diǎn)擊獲取