
简介这份PDF资料面向准备数据分析岗位面试的开发者与求职者围绕Python核心库Pandas整理出60道高频面试题覆盖基础概念、中级用法与高级特性三个层级帮助读者系统梳理知识点、查漏补缺。资源包共1个PDF文件大小约263KB轻量便携适合在通勤或碎片时间快速翻阅。内容按难度递进编排基础部分涉及Series与DataFrame结构、CSV读写、条件筛选、缺失值处理、分组聚合等中级部分延伸到apply映射、时间序列、MultiIndex、concat拼接、cut与qcut分箱等高级部分则讨论内存优化、分块读取大文件、Categorical性能改进、SQL交互、窗口函数与自定义聚合等实战话题。每道题均配有代码示例与简要说明可直接对照练习。目前已有1288人学习下载适合需要集中突破Pandas考点、构建完整知识框架的初中级数据分析学习者。1. 从一份 90 题的 Pandas 面试题库说起它到底能解决什么面试前三天简历上写着“熟练使用 Pandas”结果被问到loc和iloc的区别、groupby后怎么做复合运算、大文件读不进内存怎么办当场卡壳——这种场景在数据岗面试里太常见了。手头这份《Pandas面试题.pdf》就是冲着这个痛点来的它不是零散的知识点罗列而是一份从基础到高级、覆盖 90 个问题的题库按基础1-20、中级21-40、高级41-60、额外探讨81-90四个梯度组织。基础部分盯的是 Series 和 DataFrame 这两类核心结构、CSV 读写、条件筛选、缺失值处理这些日常操作中级开始涉及apply、map、cut/qcut、MultiIndex、时间序列、正则表达式高级则直接压到内存优化、Categorical 类型、SQL 交互、窗口函数、分块读取这些真正区分“会用”和“用得好”的地方。适合谁准备数据岗面试的人、刚转行想系统补 Pandas 的人以及平时写脚本但总觉得性能上不去、想回头把底层机制捋一遍的从业者。它不能替代官方文档但能当一张高频考点的地图用。2. 基础 20 题把 DataFrame 的读写筛选一次打通2.1 数据结构与 IOSeries、DataFrame 和 read_csv 的参数边界Pandas 的两大基本结构是 Series一维带索引和 DataFrame二维每列可不同 dtype。面试里问“基本数据结构有哪些”答出这两个只是及格线真正拉开差距的是能不能说清索引在其中的角色——Series 和 DataFrame 都依赖索引做对齐这也是后面merge、join出问题的根源。读 CSV 是最常被低估的一步。pd.read_csv()看着简单但参数不设对后面全是坑import pandas as pd df pd.read_csv( sales.csv, encodingutf-8, # 中文文件常见 gbk读出来乱码先查这里 dtype{order_id: str}, # 订单号这类别让 pandas 猜成 int前导零会丢 parse_dates[order_date], # 直接解析日期列省得后面再转换 na_values[, NULL, N/A] # 自定义缺失值标记 ) print(df.head(3)) print(df.dtypes)逻辑说明encoding决定中文是否乱码Windows 导出的 CSV 经常是gbkdtype强制指定列类型避免 ID 类字段被推断成数值后丢失前导零parse_dates在读取阶段就完成日期解析比读完再pd.to_datetime更省事na_values把业务系统里各种“空”的写法统一成NaN。参数怎么改如果文件有几千列、只想读其中几列加usecols[a,b]内存能省一大截。查看前几行用df.head(n)默认 5 行。选择特定列有两种写法df[col]返回 Seriesdf[[col]]返回 DataFrame这个差别在面试里经常被追问。条件筛选用布尔索引df[df[amount] 1000]或者df.query(amount threshold)后者在条件复杂时可读性更好。2.2 排序、合并、索引与缺失值四个高频操作的实操细节排序用df.sort_values(bycol, ascendingFalse)多列排序传列表by[a,b]注意ascending也要传对应长度的列表。合并两个 DataFrame 用pd.merge(df1, df2, onkey, howinner)how可选inner/left/right/outer。这里有个血泪经验合并前先确认两边的 key 列 dtype 一致一边是int64一边是objectmerge 出来全是空排查半天才发现是类型问题。设置索引用df.set_index(col, inplaceTrue)重置用df.reset_index(dropTrue)——dropTrue表示丢弃旧索引不把它变成列不加这个参数旧索引会变成一列混进数据里。缺失值处理两条路df.dropna()直接删df.fillna(value)填充。填充时别无脑填 0数值列填均值或中位数、分类列填众数更合理具体看业务含义。添加新列直接赋值df[new] df[a] df[b]删除列用df.drop(col, axis1)删行用df.drop(index_label, axis0)。输出到 CSV 用df.to_csv(out.csv, indexFalse)indexFalse几乎每次都要加否则会多出一列无名索引。遍历行不推荐iterrows()性能差且 dtype 会变常见做法是用df.itertuples()或向量化操作替代。3. 中级 20 题apply、MultiIndex 与时间序列的实战用法3.1 apply/map/cut/qcut函数映射与分箱的选型apply、map、applymap这三个函数面试出现频率极高但很多人分不清。map作用于 Series 的每个元素做值替换或映射apply作用于 Series 或 DataFrame可以按行或按列传函数applymap新版叫DataFrame.map作用于 DataFrame 的每个元素。选型原则能用向量化就不用apply能用map就不用apply因为apply本质是 Python 层循环数据量大时慢得明显。# map值映射比如把等级编码转成文字 df[level_name] df[level].map({1: 低, 2: 中, 3: 高}) # apply按列做自定义聚合 df[amount_log] df[amount].apply(lambda x: np.log1p(x)) # cut按固定边界分箱 df[age_group] pd.cut(df[age], bins[0, 18, 35, 60, 100], labels[少年, 青年, 中年, 老年]) # qcut按分位数分箱每箱样本量接近 df[score_q] pd.qcut(df[score], q4, labels[Q1, Q2, Q3, Q4])逻辑说明map的字典里没覆盖到的值会变成NaN要留意apply里用np.log1p而不是np.log是因为log1p对 0 安全cut是等宽分箱边界自己定qcut是等频分箱每箱数量大致相等。参数怎么改cut的bins传整数表示等分成几段传列表表示自定义边界qcut的q传整数是分几份传列表是自定义分位点。3.2 MultiIndex、拼接与时间序列多级索引和日期处理的坑MultiIndex 用df.set_index([col1, col2])创建筛选时用.loc配合元组df.loc[(A, x)]。多级索引的好处是能在高维数据上做切片但坑在于reset_index后列名层级会变复杂unstack和stack来回转容易把列顺序搞乱。拼接用pd.concat([df1, df2], axis0)纵向堆叠axis1横向拼接注意ignore_indexTrue能重置索引避免重复。时间序列是中级到高级的过渡考点。字符串转日期用pd.to_datetime(df[date], format%Y-%m-%d)指定format比让 pandas 自动推断快很多。按时间分组用df.resample(M).sum()M是月末W是周D是日。处理时区用dt.tz_localize(Asia/Shanghai)本地化dt.tz_convert(UTC)转换。缺失日期用df.asfreq(D)补齐频率再用interpolate()插值。df[date] pd.to_datetime(df[date]) df df.set_index(date).sort_index() monthly df.resample(M).agg({amount: sum, qty: mean})逻辑说明resample前必须确保索引是 DatetimeIndex 且已排序否则结果会错乱agg里传字典可以不同列用不同聚合函数。参数怎么改resample的频率字符串换成W、Q、Y就是周、季、年。4. 高级 20 题内存优化、分块读取与 SQL 交互4.1 dtype 与 Categorical把内存压下来的具体手段高级部分第一个绕不开的问题就是内存。Pandas 默认读进来的整数是int64、浮点是float64很多列根本用不到这么大。优化手段数值列降位df[id] df[id].astype(int32)浮点降成float32重复率高的字符串列转成Categorical内存能降一个数量级。# 查看内存占用 print(df.memory_usage(deepTrue).sum() / 1024**2, MB) # 数值降位 df[user_id] pd.to_numeric(df[user_id], downcastinteger) df[amount] pd.to_numeric(df[amount], downcastfloat) # 字符串转 Categorical df[city] df[city].astype(category) # 优化后再看 print(df.memory_usage(deepTrue).sum() / 1024**2, MB)逻辑说明memory_usage(deepTrue)才会真正统计 object 列里字符串的内存不加deep只算指针大小数字会偏小downcast自动选能装下的最小类型Categorical适合唯一值远少于总行数的列如果每行都不同反而更占内存。参数怎么改downcastunsigned用于非负整数能再省一点。4.2 分块读取与 SQL 交互大文件和数据源对接DataFrame 大到装不进内存用chunksize分块读chunk_iter pd.read_csv(big_file.csv, chunksize100000) result [] for chunk in chunk_iter: # 每块先过滤再聚合减少累积数据量 filtered chunk[chunk[status] paid] result.append(filtered.groupby(city)[amount].sum()) final pd.concat(result).groupby(level0).sum()逻辑说明chunksize指定每块行数返回的是迭代器不是 DataFrame关键是在循环内先做过滤和聚合别把每块原样存下来否则内存照样爆。参数怎么改chunksize根据机器内存调一般 10 万到 50 万行一块比较稳。和 SQL 数据库交互用pd.read_sql()from sqlalchemy import create_engine engine create_engine(sqlite:///demo.db) df pd.read_sql(SELECT city, SUM(amount) AS total FROM orders GROUP BY city, engine)逻辑说明create_engine建连接read_sql直接执行 SQL 返回 DataFrame能下推到数据库算的聚合就别拉回本地算这是性能分水岭。参数怎么改read_sql的params参数支持传参防注入chunksize同样支持分块。5. 避坑与排查五个高频翻车现场5.1 SettingWithCopyWarning链式赋值引发的静默失败现象执行df[df[a] 1][b] 0后没有任何报错但df里的值根本没变或者弹出SettingWithCopyWarning。原因df[df[a] 1]返回的是视图还是副本不确定Pandas 无法保证赋值落到原 DataFrame 上。解决用.loc一步到位——df.loc[df[a] 1, b] 0明确告诉 pandas 是在原数据上改。5.2 merge 后行数暴涨key 列有重复值现象两个 DataFrame 各 1000 行merge 完变成 5000 行。原因key 列在某一侧存在重复值笛卡尔积把行数放大了。解决merge 前先df[key].duplicated().sum()查重复确认业务上 key 是否应该唯一如果不唯一想清楚是要保留所有组合还是先去重。5.3 日期解析失败格式不统一导致 NaT现象pd.to_datetime后一堆NaT明明肉眼看着都是日期。原因列里混了多种格式比如2024-01-01和01/01/2024并存pandas 推断不出来。解决加formatmixed新版支持或errorscoerce先转、再单独处理失败的行别让整列静默变 NaT。5.4 groupby 后复合运算写错agg 和 apply 混用现象想先求和再求平均写了df.groupby(k)[v].sum().mean()结果得到的是一个标量而不是按组的结果。原因.sum()之后已经是 Series.mean()是对整个 Series 求平均。解决用agg传多个函数df.groupby(k)[v].agg([sum, mean])或者apply里写自定义函数。5.5 中文列名读取乱码编码没指定现象read_csv后列名全是乱码。原因文件是gbk或gb18030编码默认按utf-8读。解决pd.read_csv(f.csv, encodinggbk)还不行就试gb18030再不行用chardet检测。6. 进阶技巧用 eval 和 query 把复杂表达式写快写短到高级阶段eval和query是两个容易被忽略但很实用的工具。它们底层用 numexpr 做计算在大数据量下比普通 Python 表达式快而且语法更接近自然写法。# 普通写法 df[total] df[price] * df[qty] * (1 - df[discount]) # eval 写法大数据量下更快且不产生中间临时对象 df.eval(total price * qty * (1 - discount), inplaceTrue) # query 筛选比布尔索引可读性好 result df.query(price 100 and qty 10 and city 北京) # 引用外部变量用 threshold 500 result df.query(amount threshold)逻辑说明eval的inplaceTrue直接改原 DataFrame不加则返回新对象query里字符串用单引号包住外层用双引号或者反过来别嵌套同种引号符号用来引用 Python 变量。参数怎么改eval的engine参数可以指定python强制用 Python 引擎调试时有用。验证优化效果有个笨办法但很管用改完一段代码用%timeit跑一下或者前后各打一次df.memory_usage(deepTrue).sum()数字不会骗人。我一般还会在 notebook 里留一个df.sample(5)的检查点每次数据变换后看一眼确认没把列搞错、没把行数搞飞。从那以后我每次拿到新数据集第一件事就是df.info()加df.head()加df.dtypes三连先把类型和缺失情况摸清楚再动手省得写到一半才发现日期列是字符串、ID 列被读成了浮点。这份题库的价值不在于背答案而在于把每个问题当成一次自检——哪题卡住了哪块就是该补的。希望帮到你。本文还有配套的精品资源点击获取