Airbnb数据清洗与整形:pandas实战处理脏数据全流程
做数据分析的人经常遇到一个场景从网上下载了一份看起来很规整的数据集比如 Airbnb Listings打开一看密密麻麻的字段有价格、有评论、有坐标、有房东信息。你以为接下来可以直接建模了结果df.info()一跑发现价格是字符串、缺失值占了三成、同一套房源重复出现了五次甚至还有经纬度在海洋里的数据。这时候才意识到真正决定分析项目成败的往往不是后面用了什么高级模型而是前面这两个环节数据清洗Data Cleaning和数据整形Data Shaping。这篇文章就以 Airbnb Listings 数据集为例完整拆解一份原始房源数据从“没法用”到“能用、好用”的全过程。我们会先讲清楚清洗和整形各自解决什么问题再给出可复制的 Python 代码最后补充实际项目中的排查思路和工程建议。读完这篇文章你不仅会处理 Airbnb 数据还能把同样的方法迁移到电商商品、招聘信息、二手房挂牌等其他表格型数据集上。1. 这篇文章真正要解决的问题很多初学者对数据清洗有个误会觉得它就是“删掉空值”“去一下重复”属于体力活没什么技术含量。但真实项目里数据清洗和整形往往是耗时最久、最容易出错、也最影响最终结论质量的环节。曾有统计说数据分析师 60% 以上的时间花在数据准备上这个比例放在 Airbnb 这类真实数据集上一点都不夸张。Airbnb Listings 数据集之所以适合拿来学习是因为它具备真实业务数据的几乎所有典型问题字段类型错乱价格列里包含了$、,甚至可能是$1,200.00这种格式pandas 默认读进来是字符串。缺失值复杂有些字段缺失是可以直接删的有些字段缺失需要填充还有些字段缺失本身就是一种业务信号。重复数据同一房源可能因为房东多次更新、爬虫重复抓取而出现多行记录。异常值价格可能填成了 0评论数可能是天文数字经纬度可能完全偏离城市范围。存储格式不适合分析日期是字符串、卧室数写在文本里、多个设施用逗号拼在一个单元格里比如WiFi,Kitchen,Heating。如果跳过这些问题直接建模轻则指标失真重则整个分析结论被带偏。比如价格列不转成数值df[price].mean()就会直接报错如果错误地忽略了重复项统计房源数量时会虚高如果不对异常价格做处理中位数可能被几个极端值拉到一个完全不符合市场认知的位置。这篇文章要解决的问题就是建立一套可复用的 Airbnb Listings 数据清洗与数据整形流程。我们会从最原始的 CSV 文件开始一步一步完成数据加载、字段检查、缺失值处理、重复值处理、异常值处理、类型转换、特征提取和宽表转长表。每一步都会解释“为什么这么做”而不是只给代码。2. 数据清洗与数据整形到底差在哪先做一个概念区分。很多文章把 Data Cleaning 和 Data Shaping 混在一起讲但在工程实践中它们的职责边界很清晰。数据清洗Data Cleaning解决的是“数据对不对”的问题。它处理的是脏数据包括缺失值、重复值、异常值、格式错误、类型错误、不一致的取值等。清洗的目标是让每一行数据真实、准确、可比较。比如把$100.00变成100.0把3 beds变成3把明显偏离城市范围的经纬度删除这些都是清洗。数据整形Data Shaping解决的是“数据好不好用”的问题。它处理的是数据的组织方式包括列的选择与重命名、行与列的转换、从现有字段中提取新特征、把宽表变长表、把长表变宽表等。整形不改变数据本身的真实性但会改变数据的结构让它更适合后续可视化、建模或统计分析。比如从last_review日期中提取出年份和月份把amenities从逗号分隔的字符串拆成多个布尔列把每个房源的多个设施记录从一行展开成多行这些都是整形。可以用一句话概括清洗是把数据变干净整形是把数据变顺手。实际项目中这两个步骤往往是交替进行的。比如你发现price列有缺失值这是清洗问题但如果你想把价格按照neighbourhood_group分组填充中位数这又涉及分组和转换属于整形的思路。所以本文不会强行把它们割裂成两条互不相干的流程而是按照“先清洗后整形”的顺序组织这样对新手最友好。下面用一个表格对比它们的核心差异对比维度数据清洗Data Cleaning数据整形Data Shaping核心问题数据对不对数据好不好用主要操作处理缺失值、重复值、异常值、类型转换列选、重命名、行列转换、特征提取典型字段price、last_review、coordinatesamenities、host_verifications、date失败后果分析结果失真分析无法开展或效率低判断标准每一行数据真实可靠数据结构适合当前分析任务3. 环境准备与数据集说明整个流程只需要 Python 环境和 pandas 库不需要额外安装机器学习框架。建议在虚拟环境中操作避免依赖冲突。以下是我推荐的安装方式python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate pip install pandas numpy jupyter版本方面pandas 的 1.x 和 2.x 都支持本文代码具体以你本机安装的版本为准。如果是在 Jupyter Notebook 里操作记得把代码按单元格拆开执行方便随时查看中间结果。数据集方面本文以 Airbnb 公开的 Listings 数据集为例。这类数据一般以 CSV 格式提供包含房源 ID、房东 ID、价格、房间类型、经纬度、评论数、最低住宿晚数、发布日期等几十个字段。你可以在 Airbnb 官方的公开数据页面获取也可以使用 Kaggle 和 Inside Airbnb 上的版本。不同渠道的字段略有差异但核心字段基本一致本文代码会在读取数据后先做字段概览所以即使字段名不完全相同也能快速调整。需要特别说明的是本文不会依赖某个特定版本的 CSV 文件。真实项目中你拿到的数据字段可能比我这里演示的多或少但只要掌握了“先概览、再清洗、后整形”的思路任何版本的 Airbnb Listings 数据都能处理。4. Airbnb Listings 数据清洗核心流程拆解从这一节开始进入正题。我们先读取数据并做初步体检然后按照“缺失值 → 重复值 → 异常值 → 类型转换”的顺序完成清洗。4.1 读取数据并做初步体检拿到 CSV 后的第一件事不是急着清洗而是先搞清楚数据长什么样。建议按下面的代码先做一轮快速体检import pandas as pd import numpy as np # 读取数据 df pd.read_csv(listings.csv) # 先看行列数 print(数据集形状:, df.shape) # 看前几行了解字段类型和大概内容 print(df.head(3).T) # 看字段类型 print(df.dtypes) # 看缺失情况 print(df.isnull().sum().sort_values(ascendingFalse).head(20))这里head(3).T是为了把一行数据转置成竖排方便观察每个字段的值。dtypes能告诉我们哪些字段被读成了对象类型哪些是数值类型。isnull().sum()则是看缺失值分布。这一步跑完你通常会看到两种情况很多字段是object类型比如price、last_review、amenities。缺失值集中在少数几个字段比如last_review、review_scores_rating、neighbourhood_group。在这个阶段不需要做任何处理先记录观察结果再进入下一步。4.2 缺失值处理先分类再决定策略缺失值处理的错误做法是直接dropna()一把梭。很多新手对所有缺失字段统一删除结果把数据集删得只剩一半或者把有业务含义的缺失变成无意义的数据损失。正确的做法是先回答三个问题这个字段的缺失占比是多少这个字段后续分析中是否需要用到缺失本身有没有业务含义比如在 Airbnb 数据中id、host_id、price这些关键字段如果缺失通常建议删除对应行因为无法填充且影响核心分析。neighbourhood_group缺失但latitude、longitude存在时可以考虑通过逆地理编码补全或者直接标记为“未知区域”。last_review缺失往往意味着该房源从未收到过评论这是一个有业务含义的信号不应该简单删除而应该在整形阶段用 0 或“无评论”标记。review_scores_rating缺失如果该房源评论数为 0那缺失是合理的不需要强行填一个分数。下面是一个实用的处理策略示例# 先看关键字段缺失比例 key_cols [id, host_id, price, last_review, review_scores_rating] missing_ratio df[key_cols].isnull().mean().sort_values(ascendingFalse) print(missing_ratio) # 策略1核心标识字段缺失直接删除 df df.dropna(subset[id, host_id, price]) # 策略2对评分类字段先看评论数评论数为0则缺失合理 # 将缺失评分填充为0表示暂无评分 df[review_scores_rating] df[review_scores_rating].fillna(0) # 策略3last_review 缺失填充为 NaT后续整形时转为“无评论” df[last_review] pd.to_datetime(df[last_review], errorscoerce)这里的关键点是先给缺失值定性再选择删除、填充还是保留。如果缺失字段用于建模且缺失比例超过 50%基本可以放弃该字段如果缺失集中在少数行直接删除这些行更省事如果缺失字段具有业务含义就不要强行填充。4.3 重复值处理不能只按整行去重数据去重也有坑。df.drop_duplicates()默认按整行完全重复来判断但实际业务场景中Airbnb 房源很可能只是部分字段重复。举例来说同一个房源被爬虫抓取了两次可能id、host_id、price完全相同但last_review因为抓取时间不同而不同。这时如果按整行去重根本去不掉。正确做法是选定一组关键字段作为去重依据。# 方案1按整行去重 df df.drop_duplicates() # 方案2按房源ID去重保留最后一次抓取记录 df df.sort_values(last_scraped, ascendingFalse).drop_duplicates(subset[id], keepfirst)如果数据里没有last_scraped字段就按id去重并保留第一条即可df df.drop_duplicates(subset[id], keepfirst)去重之后记得重置索引df df.reset_index(dropTrue)这里需要说明drop_duplicates的subset参数很灵活。比如你想知道同一个房东是不是重复发布了同样的房源可以把host_id和name组合起来判断。这个决策完全取决于业务上如何定义“重复”。4.4 异常值处理用业务常识圈定合理范围异常值的判定不能只靠统计方法还必须结合业务常识。Airbnb 数据里有几个典型场景价格字段中price为 0 是明显异常的。即使是免费房源也会用特殊字段标识不会直接把价格写成 0。price高达几万美元而房间类型只是“Private room”也很可疑。这类极端值会严重影响后续的均值计算。处理思路是先看分布print(df[price].describe())然后结合业务常识设定合理范围。比如可以认为正常房源的单晚价格应该在 10 到 2000 美元之间超出这个区间单独检查而不是直接一刀切。# 先转成数值 df[price] df[price].replace([\$,], , regexTrue).astype(float) # 查看异常分布 print(df[price].describe(percentiles[0.01, 0.05, 0.5, 0.95, 0.99])) # 用业务阈值过滤 df df[(df[price] 10) (df[price] 2000)]经纬度也可以用业务常识判断。比如目标城市是纽约那么纬度应该在 40.5 到 41.0 之间经度应该在 -74.3 到 -73.5 之间。超出这个范围的数据要么是抓取错误要么是坐标漂移。df df[(df[latitude].between(40.5, 41.0)) (df[longitude].between(-74.3, -73.5))]这种基于业务范围过滤的方式比单纯靠 3σ 原则更加稳健因为你是在用领域知识约束数据而不是让数据自己定义“正常”。4.5 类型转换用pd.to_numeric和pd.to_datetime收尾清洗的最后一步是类型转换。pandas 在读 CSV 时经常把数值列读成字符串尤其是包含货币符号、千分位分隔符时更是如此。# 价格转数值前面已经做过 df[price] df[price].replace([\$,], , regexTrue).astype(float) # 评论数转数值 df[number_of_reviews] pd.to_numeric(df[number_of_reviews], errorscoerce) # 日期转 datetime df[last_review] pd.to_datetime(df[last_review], errorscoerce) # 最低住宿晚数转整数 df[minimum_nights] pd.to_numeric(df[minimum_nights], errorscoerce).astype(Int64)这里要注意errorscoerce的作用。它会把无法转换的值变成NaN而不是直接报错中断。这在真实数据集中非常重要因为你永远不知道 CSV 里会混进什么奇怪内容。转换之后再次用df.dtypes检查确保关键字段都变成了float64、datetime64[ns]等对应类型。5. Airbnb Listings 数据整形与特征工程实战清洗完成之后数据已经“干净”了但还不一定“好用”。这一节我们专注于数据整形目标是把原始字段转换成更利于分析的结构。5.1 列选择与重命名Airbnb Listings 原始数据可能有 70 多个字段但实际分析往往只需要其中十几个。建议先做一次列选择避免后面代码频繁在字段名上打转。# 只保留分析需要的字段 cols [ id, host_id, host_name, neighbourhood_group, neighbourhood, latitude, longitude, room_type, price, minimum_nights, number_of_reviews, last_review, reviews_per_month, calculated_host_listings_count, availability_365 ] df df[cols] # 重命名为更简洁、更符合 Python 习惯的列名 df df.rename(columns{ neighbourhood_group: district, calculated_host_listings_count: host_listings_count, availability_365: available_days, number_of_reviews: review_count })重命名时推荐使用小写下划线的命名规范这样可以减少后续写代码时的大写切换。列名本身就是代码的一部分一个好的列名能节省大量沟通成本。5.2 从日期字段中提取新特征last_review是日期类型后可以方便地提取年份和月份。比如你想研究“哪个季节房源评论最多”就需要把月份单独提取出来。df[last_review_year] df[last_review].dt.year df[last_review_month] df[last_review].dt.month # 缺失日期的房源没有评论用 0 填充年份 df[last_review_year] df[last_review_year].fillna(0).astype(int) df[last_review_month] df[last_review_month].fillna(0).astype(int)这里再次体现了清洗和整形的衔接。last_review的缺失值在清洗阶段被保留为NaT到整形阶段才转化为“0年0月”这种业务语义。整个过程分成两步走每一步都清楚可控。5.3 对连续型字段做分段price是连续数值但有些分析场景下把它分成几个价格带更有价值。比如看“不同价位房源的评论数差异”用数值价格当然能做散点图但用价格带做分组对比更直观。bins [0, 50, 100, 200, 500, 5000] labels [0-50, 50-100, 100-200, 200-500, 500] df[price_range] pd.cut(df[price], binsbins, labelslabels)pd.cut是等宽分段如果数据分布极不均匀也可以用pd.qcut做等频分段让每个区间样本量接近。选哪个取决于分析目的没有绝对标准。5.4 从文本字段中提取标志位Airbnb 数据中room_type的取值有Entire home/apt、Private room、Shared room、Hotel room。如果后续建模时想把房间类型作为特征最简单的办法是 One-Hot 编码。# 房间类型独热编码 room_type_dummies pd.get_dummies(df[room_type], prefixroom) df pd.concat([df, room_type_dummies], axis1)需要注意pd.get_dummies默认生成的列名会包含原始值中的空格和斜杠比如room_Entire home/apt。这种列名在后续用字符串操作时容易出问题建议在生成后统一重命名room_type_dummies.columns [ col.lower().replace( , _).replace(/, _) for col in room_type_dummies.columns ]处理完后room_type原始列可以保留也可以删除。建议在建模前删除因为独热编码已经表达了同样的信息。5.5 逗号拼接字段的拆解Airbnb 的amenities字段是典型的“一列多值”结构比如WiFi,Kitchen,Heating,Smoke detector,Essentials这样的数据直接用于分析很困难。你很难用df[amenities].value_counts()知道有多少房源提供 WiFi因为每个单元格都包含多个设施。正确的做法是把多个值拆开。如果你只需要判断“是否包含某个设施”可以先生成标志位def has_amenity(amenities_str, keyword): return int(keyword in str(amenities_str)) df[has_wifi] df[amenities].apply(lambda x: has_amenity(x, WiFi)) df[has_kitchen] df[amenities].apply(lambda x: has_amenity(x, Kitchen)) df[has_heating] df[amenities].apply(lambda x: has_amenity(x, Heating))如果你想把设施从宽表转成长表为每个房源和每个设施生成一行记录可以使用explode# 先把字符串拆成列表 df[amenities_list] df[amenities].str.split(,) # 拆分为长表 amenity_long df.explode(amenities_list) print(amenity_long[[id, amenities_list]].head(10))explode是 pandas 整形中非常强大的方法。它的作用是把一个单元格中的列表展开成多行同时复制其他字段。这在处理标签、分类、多值属性时非常常用。5.6 长表和宽表的相互转换除了explodepivot和melt也是数据整形的高频操作。这里用一个简单例子说明它们的应用场景。假设你想按district和room_type统计平均价格初始数据是每个房源一行。用pivot_table可以把这个长表转换成以district为行、room_type为列的宽表pivot_price df.pivot_table( indexdistrict, columnsroom_type, valuesprice, aggfuncmean ) print(pivot_price)反过来如果你从某个接口拿到的是宽表数据每一行是一个district每一列是一种room_type但你想用 matplotlib 或 seaborn 画分组柱状图就需要转回长表。这时候用meltlong_price pivot_price.reset_index().melt( id_varsdistrict, var_nameroom_type, value_nameavg_price ) print(long_price.head())长表和宽表的转换是数据整形里最考验理解力的部分。记住一个核心规则行是样本、列是特征就是宽表用多行表达一个样本的多个属性就是长表。分析建模常用宽表可视化绘图和部分统计模型常用长表。6. 运行结果与效果验证清洗和整形的代码写完不是跑完没报错就算成功。你需要一套验证方法来确认每一步都做对了。6.1 验证清洗效果清洗完成后的验证清单# 1. 没有缺失值或缺失值已按业务规则处理 print(清洗后缺失值总数:, df.isnull().sum().sum()) # 2. 没有重复房源 print(房源 ID 重复数:, df[id].duplicated().sum()) # 3. 关键字段类型正确 print(df[[price, review_count, last_review]].dtypes) # 4. 价格字段的统计量符合业务预期 print(df[price].describe()) # 5. 数据范围没有异常 print(经纬度范围:, df[latitude].min(), df[latitude].max(), df[longitude].min(), df[longitude].max())预期输出中缺失值总数应该为 0 或者严格等于你刻意保留的、具有业务含义的缺失值。id重复数应该是 0。price应该是float64review_count应该是数值类型last_review应该是datetime64[ns]。价格的最大值不超过你设定的业务阈值。6.2 验证整形效果整形后的验证重点在于结构是否符合后续分析需要。# 1. 新特征是否生成 print(df.columns.tolist()) # 2. 价格分段是否均匀分布 print(df[price_range].value_counts()) # 3. 独热编码列是否只有 0/1 print(df[[room_entire_home_apt, room_private_room, room_shared_room]].apply(lambda x: x.unique())) # 4. 长表展开后每个房源的设施行数是否准确 amenity_long_counts amenity_long.groupby(id).size() print(每个房源平均设施数:, amenity_long_counts.mean())如果某个price_range区间内房源数极少比如 0 个说明你的分箱边界可能不合理需要调整 bins。如果独热编码列出现了大于 1 的值说明room_type列存在异常值需要回到清洗阶段处理。6.3 用可视化快速验证除了打印统计量画图是发现数据问题的另一个高效手段。import matplotlib.pyplot as plt # 检查价格分布 df[price].hist(bins50) plt.title(Price Distribution After Cleaning) plt.xlabel(Price) plt.ylabel(Count) plt.show()如果价格分布仍然出现极端长尾比如右侧拖出很长一条尾巴并且明显不符合业务认知就需要回到异常值过滤步骤调整阈值。如果分布相对集中整体呈右偏形态这是长尾数据的正常表现可以接受。7. 常见问题与排查思路数据清洗和整形过程中有几个问题几乎每个人都会遇到。这里整理成表格方便你直接对照排查。问题现象可能原因排查方式解决方案pd.read_csv后价格列是 objectCSV 中包含$、,等符号查看df[price].head(10)确认格式用replace去掉符号后astype(float)dropna()后数据量骤降缺失值占比过高不该统一删除先计算各字段缺失比例分字段制定策略不要dropna()一把梭df[price].mean()报错列类型仍是字符串查看df.dtypes先做类型转换再计算日期字段转 datetime 失败包含NaT或非法格式串用errorscoerce后检查新产生的缺失值修正源格式或统一填充规则去重后 ID 仍有重复重复行的id相同但其他字段不同检查df[id].duplicated().sum()按 ID 去重时指定subset[id]独热编码生成的列名带特殊字符原始分类取值包含空格和斜杠打印df[room_type].unique()独热编码后统一重命名列名价格异常值导致均值远高于中位数存在极端高价或 0 价用describe(percentiles[...])看分布按业务阈值过滤或做分箱explode后数据量暴增设施字段包含大量值检查展开前后行数差异确认展开口径是否符合业务需求这里特别想强调一个新手容易犯的错误看到read_csv不报错就以为数据至少能用了。实际上pandas 在数据类型解析失败时默认不会报错而是把整列读成object类型。所以不报错不等于数据类型正确必须在清洗后主动检查dtypes。8. 最佳实践与工程建议数据清洗和整形做多了以后会发现有章可循。下面这些建议来自实际项目中的经验总结能帮你少走很多弯路。8.1 清洗流程要写成函数而不是脚本很多人习惯在 Notebook 里从头到尾写一长串清洗代码跑完就完事。但真实项目的麻烦在于数据源会更新比如 Airbnb 每月发布一次新数据。如果清洗逻辑是散落的一堆单元格每次更新都要人工重跑很容易漏步骤。建议把清洗和整形封装成函数def clean_listings(df): Airbnb Listings 清洗函数 df df.copy() df df.drop_duplicates(subset[id], keepfirst) df df.dropna(subset[id, host_id, price]) df[price] df[price].replace([\$,], , regexTrue).astype(float) df[last_review] pd.to_datetime(df[last_review], errorscoerce) df df[(df[price] 10) (df[price] 2000)] return df.reset_index(dropTrue) def shape_listings(df): Airbnb Listings 整形函数 df df.copy() df[last_review_year] df[last_review].dt.year df[last_review_month] df[last_review].dt.month df[price_range] pd.cut(df[price], bins[0, 50, 100, 200, 500, 5000]) return df封装成函数之后每次数据更新只需要重新执行clean_listings(new_df)而且函数名本身就在记录流程代码的可读性和可维护性能提升一个档次。8.2 保留原始数据清洗结果另存一个非常实用的习惯永远保留一份原始数据清洗后的数据另存为新的变量或者新的文件。# 先备份 raw_df pd.read_csv(listings.csv) df raw_df.copy() # 在 df 上执行清洗和整形 ...这样做的好处是如果清洗规则需要调整比如修改价格阈值你不需要重新下载数据只需要重新执行从raw_df.copy()开始的单元格。另一个好处是当你需要追溯某条数据为什么被删除时可以回到原始数据检查。8.3 每一步清洗都要可审计在团队协作或生产环境中数据清洗规则必须有记录。最简单的做法是在 Notebook 中为每一个处理步骤写好注释并且说明依据。# 删除价格小于10美元或大于2000美元的房源 # 依据业务上低于10美元视为测试房源高于2000美元视为极端高价 # 影响影响约 1.2% 的行需业务确认后执行 df df[(df[price] 10) (df[price] 2000)]如果团队使用版本管理工具清洗脚本也应该纳入管理。数据清洗不是一次性工作它跟业务代码一样需要 review需要回溯。8.4 区分处理与分析避免过度清洗数据清洗有一个容易走偏的方向为了追求“完美数据”而过度清洗。比如某个字段缺失率达到 30%有人会想尽办法用机器学习模型去填充它。但在大多数分析场景下删除该字段或者简单地标记缺失比复杂填充更稳妥。原则是清洗的目的是让数据能回答问题而不是让数据完美。如果某个字段在你要回答的问题中根本用不到就不需要为它花费大量时间。先明确分析目标再决定清洗的深度效率会高很多。8.5 在项目早期就约定列名规范Airbnb 数据集来自公开渠道列名比较混乱比如number_of_reviews和reviews_per_month很相似容易混淆。在项目开始时就统一重命名可以避免后面写出df[number_of_reviews]和df[reviews_per_month]混用的情况。推荐的命名规范是全部小写单词间用下划线连接。例如review_count、available_days、host_listings_count。这样写代码时不需要记忆大小写也符合 Python 社区的习惯。8.6 注意数据来源与合规性Airbnb 公开数据集的获取和使用需要注意数据来源的授权条款。不同渠道发布的 Airbnb 数据集使用限制不完全相同有些仅限非商业用途。如果项目用于商业分析建议先确认数据的使用许可。另外Airbnb 数据中包含经纬度等空间信息在公开发表分析结果时如果房源数量较少应注意脱敏避免从细粒度坐标反推出具体房源位置。这类数据合规问题在真实项目里越来越重要建议从一开始就养成习惯。9. 总结与后续学习方向这篇文章以 Airbnb Listings 数据集为例完整走了一遍数据清洗和整形流程。核心结论可以浓缩成三句话第一数据清洗解决的是“数据对不对”的问题核心操作是缺失值、重复值、异常值和类型转换数据整形解决的是“数据好不好用”的问题核心操作是列选择、特征提取、宽表长表转换。两者不能互相替代也不该混为一谈。第二清洗和整形都不是一次性任务而是需要反复迭代、验证和审计的工程过程。每一步处理都要有依据、可追踪并且保留原始数据作为对照。第三Airbnb Listings 数据集是练习数据清洗和整形的优质材料因为它几乎包含了所有真实数据的典型问题。把这一套方法吃透之后迁移到电商订单、招聘信息、房产挂牌等数据上只需要调整字段名和业务规则即可。后续可以从这几个方向继续深入把清洗和整形结果用于探索性数据分析比如研究纽约不同区域房源的定价差异。结合 scikit-learn 构建价格预测模型理解缺失值填充方式对模型效果的影响。学习更高级的数据整形工具比如pandas的pipe链式调用、polars的高性能数据框操作。建议收藏这篇文章等真正拿到一份 Airbnb Listings 数据时照着流程走一遍再把清洗函数改造成适合自己业务的版本。数据清洗没有那么多“银弹”多做几次真实数据比看一百篇教程都管用。

相关新闻

MySQL面试核心要点与性能优化实战指南

MySQL面试核心要点与性能优化实战指南

1. MySQL面试核心要点解析作为Java开发者技术栈中不可或缺的一环,MySQL的掌握程度直接影响着面试成败。我整理了一份经过实战检验的MySQL八股知识体系,涵盖高频考点和易错细节,这些内容曾帮助我在3个月内通过6家互联网大厂的技术面试。1.1 存…

2026/8/26 3:04:53 阅读更多 →
Java开发者转型全栈工程师的面试实录与经验分享

Java开发者转型全栈工程师的面试实录与经验分享

1. 项目概述"从Java全栈到前端框架:一位资深开发者的面试实录"这个标题背后,反映的是当前技术岗位面试中一个非常普遍的现象——企业对复合型人才的需求正在急剧增长。作为一名经历过上百场技术面试的面试官,我深刻体会到&#xff…

2026/8/26 3:03:53 阅读更多 →
Codex Skill 装得多不如配得对:视频处理实战指南

Codex Skill 装得多不如配得对:视频处理实战指南

最近有个现象很有意思:很多人拿到 Codex 之后,第一件事不是先想清楚要拿它做什么,而是到处找 Skill、装 Skill。社区里有人一口气装了几十个,甚至把做 PPT 的、写周报的、搞数学建模的、生成表情包的全都塞进去,感觉“…

2026/8/26 3:03:53 阅读更多 →

最新新闻

Hutool IdUtil深度解析:从UUID到Snowflake的分布式ID生成实战

Hutool IdUtil深度解析:从UUID到Snowflake的分布式ID生成实战

1. 从“又要一个ID”到“选对工具”:为什么我们需要Hutool的IdUtil做后端开发,尤其是涉及到数据库存储、分布式系统或者消息队列,生成唯一标识符(ID)几乎是每天都要面对的“日常任务”。我猜你肯定经历过这样的场景&am…

2026/8/26 3:49:10 阅读更多 →
RSA功耗分析实战:从SPA到CPA及防护绕过

RSA功耗分析实战:从SPA到CPA及防护绕过

1. 为什么时隔多年又回头折腾 RSA 功耗分析1.1 上次做 RSA 功耗分析是什么时候老实说,我第一次接触 RSA 功耗分析已经是很多年前的事了。那会儿刚入行做嵌入式安全,手头是一块老掉牙的 8 位智能卡芯片,示波器还是模拟的,电流探头靠…

2026/8/26 3:49:10 阅读更多 →
从载流子输运到pn结和MOSFET:芯片工作的核心物理逻辑

从载流子输运到pn结和MOSFET:芯片工作的核心物理逻辑

半导体基础系列(第4篇):从载流子输运到器件工作的核心逻辑做半导体这一行,最常被问的一个问题就是:“学了一堆能带图、载流子浓度,到底跟芯片有什么关系?”前面三篇我们一直在打地基&#xff0c…

2026/8/26 3:49:10 阅读更多 →
数学建模竞赛Python实战:从模型选型到代码实现的完整工具箱

数学建模竞赛Python实战:从模型选型到代码实现的完整工具箱

1. 项目概述:一份“硬核”的数学建模竞赛解题包又到了一年一度的数学建模竞赛季,无论是五一赛、国赛还是美赛,拿到赛题后,很多同学的第一反应往往是:这个题用什么模型?代码怎么写?有没有现成的参…

2026/8/26 3:49:10 阅读更多 →
千万级校招系统架构设计与性能优化实战

千万级校招系统架构设计与性能优化实战

1. 校招季的技术修罗场:当简历洪流遇上系统瓶颈每年8-10月,国内头部互联网公司的校招系统都会经历一场真实的技术压力测试。去年秋招季,某大厂HR系统监控面板上的数字让我记忆犹新——单日峰值简历处理量突破87万份,整个校招周期累…

2026/8/26 3:49:10 阅读更多 →
MCX系列与MCUXpresso IDE:降低嵌入式开发返工时间的关键实践

MCX系列与MCUXpresso IDE:降低嵌入式开发返工时间的关键实践

嵌入式开发里最容易被低估的敌人,不是Bug,而是“返工型时间消耗”。引脚复用表查错、时钟树配置翻车、换一颗料号整个工程重新搭、SDK版本不匹配导致的莫名编译错误……这些事情不谈技术难度,但每一样都在啃项目排期。NXP这些年推的MCX MCUs和…

2026/8/26 3:48:10 阅读更多 →

日新闻

Python random 模块常用函数详解:从入门到实战

Python random 模块常用函数详解:从入门到实战

目录 1. 引言2. 准备工作3. 基础随机函数4. 序列相关函数5. 随机种子与复现6. 实战案例7. 注意事项8. 常见问题与排查9. 总结 1. 引言 摘要: 本文系统介绍 Python 标准库 random 模块中最常用的随机数生成函数。内容涵盖基础随机函数(random()、unifor…

2026/8/26 0:00:40 阅读更多 →
《Microsoft Sql server 2008 Internals》读书笔记--第三章Databases and Database Files(2)

《Microsoft Sql server 2008 Internals》读书笔记--第三章Databases and Database Files(2)

《Microsoft Sql server 2008 Internals》索引目录: 《Microsoft Sql server 2008 Internals》读书笔记--目录索引 在上篇文章中,主要介绍了创建数据库的基本语法和FileGroup的初步知识。需要注意的是: 关于FileGroup 如果你的系统是用Raid设备直接存…

2026/8/26 1:18:18 阅读更多 →
政务AI智能体怎么建?三种模式、三步路径与四个误区

政务AI智能体怎么建?三种模式、三步路径与四个误区

政务AI智能体已经从概念试点阶段,转入了政务服务的常态化落地应用;在实际使用过程中,它能自主理解办事需求、辅助完成填报申报、开展材料预审,并联动多个系统协同作业,真正嵌入到政务办理的全流程当中。但在落地推进过…

2026/8/26 1:18:18 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/25 3:38:12 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/25 3:38:18 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/25 3:38:23 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/24 20:22:44 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/25 10:31:12 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/26 1:24:05 阅读更多 →