引言
欢迎来到这份全面的指南,它将为你提供知识和信心,让你在 Pandas 相关的面试中脱颖而出。无论你是一名初出茅庐的数据分析师、经验丰富的数据科学家,还是机器学习工程师,掌握 Pandas 都是高效数据处理和分析的关键。本文档系统地涵盖了广泛的主题,从基本概念和实际数据操作场景,到高级技术、性能优化以及生产环境中的实际应用。准备好深化你的理解,磨练你的技能,确保你为遇到的任何 Pandas 挑战做好充分准备。

Pandas 基础概念
Pandas 中有两个主要的数据结构,它们有什么区别?
答案:
两个主要的数据结构是 Series 和 DataFrame。Series 是一维的、带标签的数组,可以容纳任何数据类型,类似于电子表格中的一列。DataFrame 是二维的、带标签的数据结构,其列可能包含不同类型的数据,类似于表格或电子表格。
请解释 Pandas 中“索引”(index)的概念。它为什么重要?
答案:
Pandas 中的索引是行或列的标签,提供了一种唯一标识和访问数据的方式。它对于高效的数据对齐、选择和操作至关重要,尤其是在合并或连接 DataFrame 的操作中。
如何从 Python 字典创建 Pandas Series 和 DataFrame?
答案:
Series 可以从字典创建,其中键成为索引,值成为数据。DataFrame 可以从字典创建,其中键成为列名,值是代表列数据的列表/数组。例如:pd.Series({'a': 1}) 和 pd.DataFrame({'col1': [1, 2]})。
loc 和 iloc 在数据选择方面有什么区别?
答案:
loc 主要基于标签进行索引,用于通过行和列标签选择数据。iloc 基于整数位置进行索引,用于通过行和列的整数位置选择数据。loc 包含结束标签,而 iloc 不包含结束整数。
如何处理 Pandas DataFrame 中的缺失值(NaN)?
答案:
可以使用 isnull() 或 isna() 方法检测缺失值,使用 dropna() 删除包含 NaN 的行/列,或者使用 fillna() 将 NaN 替换为指定值(例如,均值、中位数或常量)。选择哪种方法取决于数据和分析目标。
请解释 Pandas 中的 groupby() 方法。
答案:
groupby() 方法用于根据一个或多个列的值对 DataFrame 的行进行分组。它返回一个 GroupBy 对象,然后可以使用该对象对每个组应用聚合函数(例如,sum()、mean()、count()),从而实现拆分 - 应用 - 合并(split-apply-combine)操作。
Pandas 中 apply() 的作用是什么?
答案:
apply() 方法用于沿 DataFrame 或 Series 的轴应用函数。它非常灵活,允许你逐元素、逐行或逐列应用自定义函数或内置函数,这对于内置方法未涵盖的复杂转换非常有用。
如何在两个 DataFrame 之间执行合并操作?
答案:
pd.merge() 函数用于基于共同的列或索引合并两个 DataFrame,类似于 SQL 的 join 操作。你需要指定 DataFrame、键列(on 或 left_on/right_on)以及 join 的类型(how - 例如 'inner', 'outer', 'left', 'right')。
copy() 和直接赋值 DataFrame 有什么区别?
答案:
直接赋值 DataFrame(例如 df2 = df1)会创建一个视图,这意味着 df2 只是 df1 的另一个指向相同底层数据的引用。对 df2 的更改会影响 df1。使用 df2 = df1.copy() 会创建一个深拷贝,使 df2 成为一个独立的数据帧,拥有自己的数据,因此对 df2 的更改不会影响 df1。
如何更改 DataFrame 中某一列的数据类型?
答案:
你可以使用 astype() 方法更改列的数据类型。例如,df['column_name'] = df['column_name'].astype('int') 将该列转换为整数类型。这对于确保正确的数据操作和内存效率至关重要。
数据操作与转换场景
如何处理 Pandas DataFrame 中的缺失值(NaN)?
答案:
可以使用 df.dropna() 删除包含 NaN 的行/列,或者使用 df.fillna() 将 NaN 替换为特定值(例如,0、均值、中位数或前向/后向填充)。选择哪种方法取决于数据和分析目标。
请解释 loc 和 iloc 在 DataFrame 索引方面的区别。
答案:
loc 主要基于标签进行索引,意味着你使用行/列标签来选择数据。iloc 基于整数位置进行索引,意味着你使用整数位置(从 0 到 length-1)来选择数据。两者都可以用于单个选择或切片。
如何在 Pandas 中对两个 DataFrame 执行类似 SQL 的 JOIN 操作?
答案:
类似 SQL 的 JOIN 操作使用 pd.merge() 函数执行。你需要指定 DataFrame、用于共同列的 on 参数,以及用于 join 类型的 how 参数(例如 'inner', 'left', 'right', 'outer')。
描述如何对 DataFrame 中的数据进行分组并应用聚合函数。
答案:
数据使用 df.groupby() 方法进行分组,指定用于分组的列。分组后,可以对分组对象应用聚合函数,如 sum()、mean()、count()、min() 或 max(),以汇总数据。
如何将自定义函数应用于 DataFrame 的列或行?
答案:
对于列操作,使用 df['column'].apply(custom_func)。对于跨多列的行操作或逐元素操作,使用 df.apply(custom_func, axis=1) 处理行,或使用 df.apply(custom_func, axis=0) 处理列。为了性能,通常优先使用向量化操作。
pivot_table 的用途是什么,它与 groupby 有何不同?
答案:
pivot_table 用于创建类似电子表格的透视表作为 DataFrame,通过一个或多个键列汇总数据。虽然 groupby 基于一个或多个键聚合数据,但 pivot_table 还允许取消堆叠和重塑数据,将其转换为具有指定索引、列和值的新表格格式。
如何更改 Pandas DataFrame 中某一列的数据类型?
答案:
可以使用 astype() 方法更改列的数据类型,例如 df['column'] = df['column'].astype('int') 或对于日期使用 df['column'] = pd.to_datetime(df['column'])。这对于正确的数据操作和分析至关重要。
请解释如何从 DataFrame 中删除重复行。
答案:
可以使用 df.drop_duplicates() 方法删除重复行。默认情况下,它会考虑所有列并保留第一次出现的行。你可以使用 subset 参数指定列的子集,并指定是保留 'first'(第一个)、'last'(最后一个)还是 False(所有)重复项。
如何根据 DataFrame 中的现有列创建新列?
答案:
可以通过对现有列执行操作来创建新列,例如 df['new_col'] = df['col1'] + df['col2']。对于更复杂的逻辑,可以使用带有 lambda 函数或已定义函数的 apply() 方法,或者使用 np.where() 进行条件赋值。
Pandas 中 stack() 和 unstack() 的作用是什么?
答案:
stack() 将 DataFrame(或 Series)从宽格式转换为长格式,将最内层的列索引转换为最内层的行索引。unstack() 执行相反的操作,将最内层的行索引转换为最内层的列索引,将长格式转换为宽格式。
如何按一列或多列对 DataFrame 进行排序?
答案:
可以使用 df.sort_values() 方法对 DataFrame 进行排序。你需要指定 by 参数,其中包含列名或列名列表。ascending 参数(默认为 True)控制排序顺序,而 inplace=True 可以直接修改 DataFrame。
何时应使用 pd.concat() 而非 pd.merge()?
答案:
当 DataFrame 具有相似的结构或你想将它们堆叠起来时,pd.concat() 用于沿轴(按行或按列)组合 DataFrame。当你想基于共同的列(键)组合 DataFrame,类似于 SQL join,并且想合并来自不同来源的相关数据时,则使用 pd.merge()。
高级 Pandas 技术与优化
如何优化 Pandas DataFrame 的内存使用,尤其是在处理大型数据集时?
答案:
优化内存使用包括使用合适的数据类型(例如,低基数字符串使用 category,小整数使用 int8/int16),向下转换数值类型,以及避免不必要的对象列。df.info(memory_usage='deep') 方法有助于识别内存占用大户。
请解释 Pandas 中 apply()、map() 和 applymap() 的区别以及何时使用它们。
答案:
map() 用于 Series,进行逐元素应用。apply() 用于 Series 或 DataFrame,沿轴(行/列)应用函数。applymap() 用于 DataFrame,对所有元素进行逐元素应用。在可能的情况下,map() 和 apply() 的性能通常优于 applymap()。
何时应使用 groupby().transform() 而非 groupby().apply()?
答案:
transform() 返回一个具有与原始 DataFrame 相同索引的 Series/DataFrame,将聚合结果广播回原始形状。apply() 更灵活,允许使用任意函数,该函数可以返回 Series、DataFrame 或标量,但它可能不会保留原始索引或形状。
请描述 Pandas 中“链式操作”(chaining)的概念,以及为什么通常不推荐使用它。
答案:
链式操作是指在一行代码中对 DataFrame 执行多个操作,而不分配中间结果。不推荐使用它是因为它可能由于视图与副本的歧义而导致 SettingWithCopyWarning,使代码更难调试,并可能产生不正确的结果。显式分配中间结果更安全。
如何处理 Pandas 中的 SettingWithCopyWarning?
答案:
当 Pandas 无法明确确定操作是作用于视图还是副本时,就会出现此警告。要解决此问题,请使用 .loc[] 进行显式索引和赋值,确保在打算修改时操作的是副本,如果不是则操作的是视图。例如,df.loc[rows, cols] = value。
除了基本的向量化操作外,还有哪些常见的方法可以加速大型 DataFrame 的操作?
答案:
除了向量化,还可以考虑使用 Numba 对自定义函数进行即时编译(JIT),使用 Cython 编写性能关键部分的代码(用 C 语言),或者使用 Dask 进行内存外(out-of-core)和并行计算。对于特定任务,Pandas 的内置方法通常经过高度优化。
请解释 pd.Categorical 数据类型的意义及其优点。
答案:
pd.Categorical 用于表示分类数据,其值仅限于一组固定的可能性。它通过存储整数而不是重复的字符串来节省内存,并且可以显著加快诸如 groupby() 和排序之类的操作,尤其对于低基数(low-cardinality)的列。
如何在不耗尽内存的情况下高效地将大型 CSV 文件读入 Pandas?
答案:
在 pd.read_csv() 中使用 chunksize 参数,分块读取文件,并迭代处理每个块。指定列的 dtype 以从一开始就优化内存使用。使用 usecols 参数选择仅需要的列。
Pandas 方法中 inplace 参数的意义是什么,为什么通常不推荐使用它?
答案:
inplace=True 会直接修改 DataFrame 而不返回新的 DataFrame,从而节省内存。但是,它会破坏方法链式调用,使调试更加困难,并且如果处理不当可能导致意外行为。通常建议将结果赋值给一个新变量。
请描述如何在 Pandas 中执行时间序列重采样和聚合。
答案:
在具有 DateTimeIndex 的 DataFrame 上使用 .resample() 方法。指定所需频率(例如,'D' 表示每日,'M' 表示每月)。然后,对重采样对象应用聚合函数,如 .mean()、.sum() 或 .ohlc()。
实际应用与问题解决
你有一个包含客户订单数据的 DataFrame,其中包含 'customer_id'、'order_date' 和 'total_amount'。如何找出总消费额排名前 5 的客户?
答案:
按 'customer_id' 对 DataFrame 进行分组,计算每个客户的 'total_amount' 总和,然后按降序排序。最后,使用 .head(5) 选择前 5 条记录。
给定一个包含 'timestamp' 列的 DataFrame,如何将年份和月份提取到两个新的独立列中?
答案:
首先,确保 'timestamp' 列是 datetime 类型。然后,使用 .dt 访问器提取年份和月份:df['year'] = df['timestamp'].dt.year 和 df['month'] = df['timestamp'].dt.month。
你有一个包含缺失值的 DataFrame。请描述两种处理缺失值的常用策略,以及何时可能选择其中一种。
答案:
两种策略是使用 df.dropna() 删除包含缺失值的行/列,或使用 df.fillna() 填充缺失值。当缺失数据量很少或随机时,dropna 是合适的。当你可以插补值(例如,均值、中位数或特定常量)而不显著扭曲数据分布时,则优先使用 fillna。
如何在两个 DataFrame df1(包含 'id' 和 'name')和 df2(包含 'id' 和 'value')之间执行左连接(left join),并保留 df1 中的所有行?
答案:
使用 pd.merge(df1, df2, on='id', how='left')。这将包含 df1 中的所有行以及 df2 中匹配的行。如果在 df2 中未找到匹配项,则会在 df2 的列中放置 NaN。
你的 DataFrame 中有一个 'price' 列,目前存储为字符串(例如,'$12.50')。如何将其转换为数值类型?
答案:
首先,使用字符串操作移除 '$' 符号:df['price'] = df['price'].str.replace('$', '')。然后,使用 pd.to_numeric(df['price']) 将该列转换为数值类型。
请描述一个你会使用 pivot_table 而不是 groupby 的场景。
答案:
pivot_table 非常适合重塑数据,创建类似电子表格的透视表,其中一个或多个列作为索引,一个或多个列作为列,并应用一个聚合函数。groupby 更通用,用于将数据拆分为组并对每个组应用函数,返回一个 Series 或 DataFrame。
如何高效地将自定义函数应用于 DataFrame 的每一行?
答案:
最有效的方法通常是使用 df.apply(axis=1) 配合 lambda 函数或已定义的函数。对于逐元素操作,如果适用,向量化的 Pandas 操作或 NumPy 函数会更快。
你需要根据一组列(例如 'customer_id' 和 'order_date')来识别并删除重复行。你会怎么做?
答案:
使用 df.drop_duplicates(subset=['customer_id', 'order_date'], keep='first')。keep='first' 保留重复集第一次出现的行,而 keep='last' 保留最后一次出现的行,keep=False 则删除所有重复项。
如何计算时间序列 DataFrame 中 'sales' 列的 7 天滚动平均值?
答案:
首先,确保 DataFrame 按日期排序。然后,使用 .rolling() 方法:df['sales_rolling_avg'] = df['sales'].rolling(window=7).mean()。这将计算当前值和前 6 个值的平均值。
你的 DataFrame 中有一个 'category' 列。如何计算每个唯一类别的出现次数?
答案:
在 'category' 列上使用 value_counts() 方法:df['category'].value_counts()。这将返回一个 Series,其中唯一值作为索引,它们的计数作为值,并按降序排序。
性能调优与最佳实践
Pandas 操作缓慢的一些常见原因是什么?
答案:
常见原因包括逐行迭代 DataFrame、低效的数据类型(例如,数字使用 'object' 类型)、过多的内存使用导致系统交换(swapping),以及非向量化操作。大型数据集自然也需要更长的处理时间。
在使用 Pandas DataFrame 时,如何避免显式循环(例如 for 循环)?
答案:
通过使用 Pandas 提供的向量化操作(例如 df['col'] * 2)、内置方法(.apply()、.map()、.transform())和 NumPy 函数来避免显式循环。这些操作是在 C 语言中实现的,速度显著更快。
请解释 .apply()、.map() 和 .applymap() 在性能和用例方面的区别。
答案:
.map() 用于 Series 级别的逐元素操作。.apply() 可以按行、按列或对 Series 进行操作。.applymap() 用于整个 DataFrame 的逐元素操作。通常,向量化操作比这三者都快,但对于 Series 来说,.map() 通常比 .apply() 快。
何时应考虑将 Numba 或 Cython 与 Pandas 一起使用?
答案:
当你遇到复杂的、无法向量化的操作并且这些操作成为性能瓶颈时,应考虑使用 Numba 或 Cython。它们可以将 Python 代码编译成机器码,为数值算法提供显著的加速,尤其是在与 .apply() 或自定义函数一起使用时。
如何优化 Pandas DataFrame 的内存使用?
答案:
通过使用适当的数据类型(例如,int8、float32、低基数字符串的 category),删除不必要的列,以及如果数据集过大无法完全载入内存时分块处理数据来优化内存。.info(memory_usage='deep') 方法有助于识别内存占用大户。
为字符串列使用 category 数据类型的优点是什么?
答案:
对于具有有限数量唯一值(低基数)的字符串列,使用 category 数据类型可以显著减少内存使用。它将字符串存储为整数代码和查找表,使得分组和排序等操作速度更快。
如何高效地将大型 CSV 文件读入 Pandas?
答案:
通过指定列的 dtype,使用 chunksize 进行迭代读取,使用 usecols 选择必要的列,以及设置 nrows 进行采样来高效读取大型 CSV 文件。这可以避免一次性将整个文件加载到内存中。
请描述 inplace=True 的重要性及其潜在的陷阱。
答案:
inplace=True 会直接修改 DataFrame 而不返回新的 DataFrame,可能节省内存。然而,它会使链式操作变得困难且可读性差,并且通常在现代 Pandas 中不推荐使用,以保持代码的清晰度和避免意外的副作用。
在执行 groupby 操作时,有哪些性能方面的考虑因素?
答案:
groupby 的性能考虑因素包括组的数量、聚合函数的复杂性以及分组键的数据类型。对分组键使用 category 数据类型可以显著加快操作速度。如果存在向量化替代方案,则应避免使用自定义 Python 函数。
如何对 Pandas 代码进行性能分析以识别性能瓶颈?
答案:
使用 cProfile 或 line_profiler 等工具对 Pandas 代码进行性能分析,以识别代码中消耗时间最多的部分。Jupyter 的 %timeit 和 %prun 魔法命令对于快速分析特定行或单元格也非常有用。
故障排除与代码调试
你通常如何开始调试一个行为不符合预期的 Pandas DataFrame?
答案:
我通常会先检查 DataFrame 的 info()、head()、tail() 和 dtypes 来了解其结构和数据类型。检查 df.shape 和 df.isnull().sum() 也有助于及早发现缺失值或意外的维度。
你遇到了 SettingWithCopyWarning 警告。这是什么意思,如何解决?
答案:
此警告表明你可能正在操作 DataFrame 切片的视图,并且你的修改可能不会反映在原始 DataFrame 中。要解决此问题,请显式使用 .loc 或 .iloc 进行链式索引,以确保你直接操作的是副本或原始 DataFrame,例如 df.loc[rows, cols] = value。
如何调试缓慢的 Pandas 操作,尤其是在处理大型数据集时?
答案:
对于缓慢的操作,我会在 Jupyter notebook 中使用 %%timeit 或 Python 的 time 模块来对特定代码块进行基准测试。cProfile 等性能分析器可以 pinpoint 瓶颈所在。通常,向量化操作而不是使用显式循环,或优化数据类型,可以显著提高性能。
你尝试执行一个操作,但 Pandas 抛出了一个 TypeError。诊断它的第一步是什么?
答案:
TypeError 通常表示操作的数据类型不匹配。我的第一步是使用 df.dtypes 检查相关列的 dtypes。然后我会确保所有涉及的列具有兼容的类型,必要时使用 astype() 进行转换。
请描述一个 NaN 值可能导致意外行为的常见场景,以及你将如何处理它。
答案:
NaN 值可能在聚合操作(例如 sum() 可能忽略它们,mean() 可能被扭曲)或执行数学运算时导致问题。我会使用 df.isnull().sum() 来识别它们,然后根据上下文和数据完整性要求,决定是使用合适的数值(均值、中位数、零)进行 fillna() 还是使用 dropna()。
如何检查和处理特定列中的重复行或重复值?
答案:
要检查重复行,我使用 df.duplicated().sum()。要根据特定列识别重复项,我会使用 df.duplicated(subset=['col1', 'col2']).sum()。要删除它们,我会使用 df.drop_duplicates() 或 df.drop_duplicates(subset=['col1'])。
你正在合并两个 DataFrame,但结果 DataFrame 的行数比预期的少。可能是什么问题?
答案:
这通常表明合并键(key)或 merge 操作的 how 参数存在问题。我会检查键列中的不匹配项(例如,拼写错误、前导/尾随空格、数据类型不一致),并确保 how 参数(例如 'inner'、'left'、'right'、'outer')与期望的结果一致。
在调试中,pd.set_option() 的目的是什么,何时会使用它?
答案:
pd.set_option() 允许你修改 Pandas 的显示选项,这对于调试至关重要。我会使用它来显示更多行(display.max_rows)、更多列(display.max_columns),或在检查大型 DataFrame 或特定值时防止列内容被截断(display.max_colwidth)。
当你尝试访问一个列时遇到 KeyError。最可能的原因是什么,如何确认?
答案:
KeyError 通常意味着你尝试访问的列名在 DataFrame 中不存在。我会通过打印 df.columns 来查看确切的列名,并检查我使用的列名是否存在拼写错误、大小写敏感问题或前导/尾随空格来确认。
Pandas 在生产环境中的应用
如何处理超出可用内存的大型数据集?
答案:
对于超出内存的数据集,策略包括分块处理数据、使用 Dask DataFrames、利用带有 Pandas UDFs 的 PySpark,或优化数据类型(例如,将 int64 转换为 int32)。高效地存储数据(例如,使用 Parquet)也有帮助。
在生产环境中使用 Pandas 时,常见的性能瓶颈是什么,如何缓解它们?
答案:
常见的瓶颈包括 for 循环、使用 Python 函数的 apply 以及低效的数据类型。缓解措施包括向量化、使用内置的 Pandas 方法、优化数据类型,以及考虑为关键路径使用 Numba 或 Cython 等工具。
请描述在生产管道中将数据摄取到 Pandas DataFrame 时,确保数据质量和完整性的策略。
答案:
策略包括模式验证(例如,使用 Pydantic 或 Great Expectations)、加载期间强制执行数据类型、妥善处理缺失值以及实施数据清理规则。定期的数据剖析(profiling)和异常检测也至关重要。
如何管理生产环境中基于 Pandas 的应用程序的依赖项和环境?
答案:
依赖项管理通常使用 pip 和 requirements.txt 或 Pipfile.lock,或者使用 conda 和 environment.yml 来完成。像 Docker 这样的容器化技术用于创建隔离的、可复现的环境以进行部署。
在生产工作负载中,何时会选择一个不同的数据处理框架(例如 Dask、Spark)而不是 Pandas?
答案:
当数据集持续超出可用内存、需要分布式计算,或者处理需要跨多台机器水平扩展时,我会选择 Dask 或 Spark。Pandas 最适合单机、内存中的操作。
如何在生产环境中记录和监控 Pandas 操作?
答案:
可以使用 Python 的 logging 模块来实现日志记录,以跟踪数据转换、错误和性能指标。监控涉及使用 Prometheus 或 Grafana 等工具跟踪资源使用情况(CPU、RAM)和关键绩效指标(KPIs)。
在生产 Pandas 脚本中,你会考虑哪些错误处理和健壮性方面的因素?
答案:
健壮性包括使用 try-except 块来处理可预见的错误(例如,文件未找到、数据解析问题)、验证输入,以及实施优雅降级或重试机制。清晰的错误消息和日志记录对于调试至关重要。
如何确保基于 Pandas 的数据管道的可复现性?
答案:
通过固定精确的库版本(例如 pandas==1.3.5)、使用 Docker 或 Conda 等工具管理环境,以及对所有代码和配置进行版本控制来确保可复现性。记录数据源和处理步骤也至关重要。
讨论在生产环境中存储 Pandas 处理过的数据时,使用 Parquet 与 CSV 的权衡。
答案:
Parquet 是一种列式二进制格式,提供更好的压缩、对特定列更快的读/写速度以及模式演进能力。CSV 是人类可读且更简单,但对于大型数据集效率较低。在生产环境中,Parquet 通常因其性能和存储效率而更受青睐。
在生产应用程序中使用 Pandas 处理 datetime 对象时,如何处理时区感知和本地化?
答案:
始终将 datetime 对象存储为 UTC,仅在显示时转换为本地时区。Pandas 的 tz_localize() 和 tz_convert() 方法用于此目的。明确时区信息以避免歧义并确保跨系统的一致性。
特定角色的 Pandas 应用(例如,数据分析师、数据科学家、机器学习工程师)
作为一名数据分析师,你收到一份包含客户数据的 CSV 文件。你会如何使用 Pandas 快速识别和汇总 'email' 和 'phone_number' 等关键列中的缺失值?
答案:
我会使用 df[['email', 'phone_number']].isnull().sum() 来计算每列的缺失值数量。要计算百分比,我会除以 len(df)。这可以快速突出显示用于报告的数据质量问题。
对于一名数据科学家,你正在准备一个用于机器学习的数据集。请描述你将如何使用 Pandas 对 'product_category' 等分类列执行独热编码(one-hot encoding),然后将其合并回原始 DataFrame。
答案:
我会使用 pd.get_dummies(df['product_category'], prefix='category') 来创建独热编码的 DataFrame。然后,我会使用 pd.concat([df, one_hot_df], axis=1) 并删除原始的 'product_category' 列来集成它。
一名机器学习工程师需要加载一个大型数据集(10GB+)用于模型训练。考虑到内存限制,你会如何使用 Pandas 高效地加载和可能地采样这些数据?
答案:
对于大型文件,我会使用 pd.read_csv(..., chunksize=...) 来分块处理,或指定 dtype 来优化内存。对于采样,在加载子集或分块后,我会使用 df.sample(frac=0.1) 或 df.sample(n=100000)。
作为一名数据分析师,你需要从一个每日销售 DataFrame 中计算月度销售趋势。假设有一个 'sale_date' 列和一个 'revenue' 列,你会如何使用 Pandas 实现这一点?
答案:
我首先会使用 pd.to_datetime() 确保 'sale_date' 是 datetime 类型。然后,我会将 'sale_date' 设置为索引,并使用 df['revenue'].resample('M').sum() 按月聚合收入。
一名数据科学家正在进行特征工程。你会如何使用 Pandas 从 'age' 列创建一个新的特征 'age_group',将客户分为 '0-18'、'19-35'、'36-60'、'60+'?
答案:
我会使用 pd.cut(df['age'], bins=[0, 18, 35, 60, np.inf], labels=['0-18', '19-35', '36-60', '60+'], right=True)。这可以有效地将数值数据分到指定的类别中。
一名机器学习工程师需要将一个 Pandas DataFrame 分割成训练集、验证集和测试集,同时确保在目标变量 'is_fraud' 上的分层抽样。你会如何使用 Pandas 和 scikit-learn 来实现?
答案:
我会使用 scikit-learn 中的 train_test_split,传入 stratify=df['is_fraud'] 来确保类别平衡。我会调用它两次:一次用于训练/临时集,然后将临时集用于验证/测试集。
作为一名数据分析师,你需要合并两个 DataFrame:customers(包含 'customer_id')和 orders(包含 'customer_id' 和 'order_id')。你会如何执行内连接(inner join)来仅查看下过订单的客户?
答案:
我会使用 pd.merge(customers_df, orders_df, on='customer_id', how='inner')。这会根据通用的 'customer_id' 列高效地合并 DataFrame,只保留匹配的行。
一名数据科学家正在处理时间序列数据,需要计算 'temperature' 列的 7 天滚动平均值。你如何在 Pandas 中做到这一点?
答案:
假设有一个 datetime 索引,我会使用 df['temperature'].rolling(window='7D').mean()。如果不是索引,我会先将 datetime 列设置为索引。
一名机器学习工程师正在部署一个需要特定列顺序和数据类型的模型。你会如何使用 Pandas 在将传入的推理数据传递给模型之前,强制执行这种结构?
答案:
我首先会使用 df = df[expected_column_order] 来重新索引 DataFrame 以强制执行列顺序。然后,我会使用 df = df.astype(expected_dtypes) 将列转换为其所需的数据类型。
作为一名数据分析师,你需要透视(pivot)一个 DataFrame 来按 'region' 和 'product_type' 汇总 'sales'。你会如何使用 pivot_table 来实现?
答案:
我会使用 pd.pivot_table(df, values='sales', index='region', columns='product_type', aggfunc='sum')。这将创建一个摘要表,其中区域作为行,产品类型作为列,总销售额作为值。
总结
掌握 Pandas 以应对数据科学面试是一段需要准备和坚持的旅程。通过认真复习这些问题并理解其根本概念,你已经武装了自己,能够自信地应对常见的挑战,并展示你在数据处理和分析方面的熟练程度。
请记住,数据科学的格局在不断发展。继续探索新功能,用多样化的数据集进行练习,并参与 Pandas 社区。你对持续学习的承诺不仅会提升你的面试表现,还将巩固你作为数据专业人士的专业知识。祝你好运!



