Pandas数据处理实战指南:从核心概念到高效应用
2026/8/2 15:28:43 网站建设 项目流程

1. 项目概述:为什么你需要这份pandas指南

如果你刚开始用Python处理数据,或者已经用了一段时间但总觉得pandas这个库用起来有点“别扭”——比如数据合并时总对不齐,筛选条件一复杂就报错,或者处理稍大点的文件就慢得让人想砸键盘——那么你来对地方了。这份指南不是官方文档的复述,也不是简单罗列几个函数。它是我在数据分析、机器学习项目里,用pandas处理过成千上万个CSV、Excel、数据库表之后,总结出来的一套“生存手册”。我会告诉你哪些功能是80%场景下最核心的,哪些“坑”我踩过并且希望你避开,以及如何写出既高效又易读的pandas代码。

pandas的核心价值在于,它用DataFrame和Series这两种数据结构,把数据变成了一个你可以灵活操作的“电子表格”。但它的强大也带来了复杂性。网上的教程往往只教df.head()df.describe(),而真正的问题,比如多级索引(MultiIndex)的切片、时间序列的重采样、或者如何避免SettingWithCopyWarning这个烦人的警告,却需要你在项目里撞得头破血流才能搞明白。这份指南的目标,就是让你跳过这些痛苦的摸索阶段,直接掌握那些能解决实际问题的、扎实的pandas技能。无论你是学生、转行的数据分析师,还是需要处理数据的开发工程师,这里的内容都能让你在数据处理的效率和质量上,立刻提升一个档次。

2. 环境搭建与核心对象理解

2.1 一步到位的环境配置方案

在深入pandas之前,一个稳定、隔离的Python环境是基石。我强烈建议不要直接在你的系统Python里安装包,那会带来版本冲突的噩梦。对于新手和老手,我最推荐的方案是使用Miniconda。

为什么是Miniconda而不是Anaconda?Anaconda预装了数百个科学计算包,体积庞大,其中很多你可能永远用不到。Miniconda只包含最基础的conda和Python,轻量干净,你可以按需构建自己的环境。安装Miniconda后,打开你的终端(Windows用Anaconda Prompt或PowerShell,Mac/Linux用Terminal),执行以下命令来创建专用于本指南的pandas环境:

# 创建一个名为pandas-guide的新环境,并指定Python版本为3.9(一个广泛兼容的稳定版本) conda create -n pandas-guide python=3.9 # 激活这个环境 conda activate pandas-guide # 使用conda安装pandas及其核心依赖numpy。conda能更好地处理非Python依赖。 conda install pandas numpy # 为了数据可视化,我们通常也会安装matplotlib和jupyter。Jupyter Notebook/Lab是交互式数据分析的绝佳工具。 conda install matplotlib jupyter

完成这些,你的专属沙箱就准备好了。任何时候进行数据分析,先conda activate pandas-guide,就能确保所有包版本一致,与系统其他项目互不干扰。

注意:如果你遇到网络问题导致conda下载缓慢,可以配置国内的镜像源(如清华、中科大源)。但请务必通过搜索引擎查找“conda 镜像 配置”等合规公开的教程进行操作,使用官方或公认的教育、科研机构提供的镜像地址。

2.2 Series与DataFrame:你必须吃透的两种数据结构

pandas的一切都围绕着两个核心对象:Series和DataFrame。你可以把它们想象成增强版的Python列表和字典。

Series是一个带标签的一维数组。这个标签就是索引(index)。创建一个Series时,如果你不指定索引,pandas会自动生成一个从0开始的整数索引。

import pandas as pd # 从一个列表创建Series s = pd.Series([10, 20, 30, 40], index=[‘a‘, ‘b‘, ‘c‘, ‘d‘]) print(s) # 输出: # a 10 # b 20 # c 30 # d 40 # dtype: int64

你可以像字典一样通过索引标签来取值(s[‘b‘]返回20),也可以进行向量化运算(s * 2会对每个元素乘以2),这比写循环高效得多。

DataFrame是一个二维的、表格型的数据结构,它包含一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。它就像一张Excel表或一个SQL数据库表。DataFrame可以看作是由多个共享同一个索引的Series组成的字典。

# 从一个字典创建DataFrame,字典的键会成为列名 data = { ‘姓名‘: [‘张三‘, ‘李四‘, ‘王五‘], ‘年龄‘: [28, 34, 25], ‘城市‘: [‘北京‘, ‘上海‘, ‘深圳‘] } df = pd.DataFrame(data) print(df)

输出如下:

姓名年龄城市
0张三28北京
1李四34上海
2王五25深圳

这里,行索引是默认的0, 1, 2,列是‘姓名‘、‘年龄‘、‘城市‘。每个列(如‘年龄‘列)本质上就是一个Series。理解到这一层,很多操作就豁然开朗了:对DataFrame的一列进行操作,其实就是对一个Series进行操作。

3. 数据IO与初步探查:你的第一道关卡

3.1 高效读取各类数据源

pandas支持读取多种格式的数据,最常用的是CSV和Excel。pd.read_csv()pd.read_excel()是你最该熟练掌握的函数。

读取CSV文件

# 最基本用法 df = pd.read_csv(‘data.csv‘) # 但实际文件往往没那么规整,需要参数调优 df = pd.read_csv(‘data.csv‘, encoding=‘gbk‘, # 处理中文编码,常用‘utf-8‘或‘gbk‘ sep=‘,‘, # 分隔符,默认为逗号,也可能是‘\t‘(制表符) header=0, # 指定第0行作为列名。如果文件没列名,设为None names=[‘col1‘, ‘col2‘], # 如果header=None,可以自定义列名 skiprows=1, # 跳过文件开头的1行(例如文件说明行) na_values=[‘NA‘, ‘null‘, ‘--‘], # 将哪些字符串识别为缺失值 dtype={‘age‘: ‘int‘, ‘score‘: ‘float‘} # 指定特定列的数据类型,提升精度和性能 )

实操心得:遇到编码错误(UnicodeDecodeError)时,别慌。先尝试encoding=‘gbk‘(常见于Windows系统生成的文件),再试encoding=‘utf-8-sig‘。对于超大的CSV文件,可以使用chunksize参数分块读取,避免内存溢出。

读取Excel文件

df = pd.read_excel(‘data.xlsx‘, sheet_name=‘Sheet1‘, # 或使用索引0,或传入多个表名组成的列表 usecols=‘A:C, E‘, # 仅读取A、B、C、E列,极大提升读取速度 skiprows=range(5) # 跳过前5行 )

从数据库(如MySQL, PostgreSQL)读取数据也很常见,通常需要配合sqlalchemy库。这能让你用SQL查询的灵活性,结合pandas分析的便利性。

3.2 快速了解你的数据:探查五件套

数据读进来后,不要急着分析。先用以下几个方法快速“摸清家底”,我称之为“探查五件套”:

  1. df.head(n)/df.tail(n):查看前/后n行数据,默认5行。这是你的第一眼。
  2. df.info():这是最重要的探查方法之一。它会打印DataFrame的简明摘要,包括索引数据类型、列数据类型、非空值数量和内存使用情况。一眼就能看出是否有列数据缺失、类型是否正确。
    df.info() # 输出会告诉你:<class ‘pandas.core.frame.DataFrame‘> # RangeIndex: 1000 entries, 0 to 999 # Data columns (total 5 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 A 950 non-null float64 # 发现A列有50个缺失值! # 1 B 1000 non-null int64 # 2 C 1000 non-null object # 3 D 980 non-null float64 # 4 E 1000 non-null bool # dtypes: bool(1), float64(2), int64(1), object(1) # memory usage: 33.3 KB
  3. df.describe():生成描述性统计摘要,仅针对数值列。包括计数、均值、标准差、最小值、四分位数和最大值。对于快速了解数值分布、发现异常值(比如年龄出现200岁)极其有用。
  4. df.shape:一个属性,返回数据形状(行数, 列数)。print(df.shape)输出(1000, 5)
  5. df.columnsdf.dtypes:查看所有列名和各列的数据类型。

花两分钟运行这五个操作,你对数据的基本情况就有了九成把握,能提前规避很多后续的错误。

4. 数据清洗与预处理:从混乱到规整

真实世界的数据几乎没有干净的。数据清洗通常占据一个数据分析项目80%的时间。以下是几个核心的清洗场景。

4.1 处理缺失值:识别与填充策略

缺失值在pandas中用NaN(Not a Number)表示。首先,用df.isnull().sum()快速查看每列有多少缺失值。

处理缺失值主要有两种策略:删除和填充。

删除缺失值:使用df.dropna()。但需谨慎,因为可能丢失大量有价值数据。

# 删除任何包含缺失值的行 df_cleaned = df.dropna() # 删除在特定列(如‘年龄‘)上有缺失值的行 df_cleaned = df.dropna(subset=[‘年龄‘]) # 只有整行全部为缺失值时才删除(比较少见但严格的策略) df_cleaned = df.dropna(how=‘all‘)

填充缺失值:使用df.fillna()。这是更常用的方法,关键在于选择合理的填充值。

# 用固定值填充,例如用0填充所有NaN df_filled = df.fillna(0) # 用每列的均值填充该列的NaN(对数值列常用) df_filled = df.fillna(df.mean()) # 用前一个有效值向前填充(对于时间序列数据很常用) df_filled = df.fillna(method=‘ffill‘) # 用后一个有效值向后填充 df_filled = df.fillna(method=‘bfill‘) # 对不同列采用不同的填充策略 df_filled = df.fillna({‘年龄‘: df[‘年龄‘].median(), # 年龄用中位数填充 ‘城市‘: ‘未知‘}) # 城市用‘未知‘字符串填充

注意事项:填充会引入偏差。用均值填充会缩小数据的方差。对于时间序列,向前/向后填充是合理的假设(即值保持不变)。对于分类数据,填充一个单独的“缺失”类别有时比填充众数更好。决策前一定要结合业务背景。

4.2 处理重复数据:去重与识别

重复行会扭曲分析结果(例如,同一用户被重复计数)。使用df.duplicated()来识别重复行,使用df.drop_duplicates()来删除它们。

# 检查所有列完全相同的重复行 duplicates = df.duplicated() # 删除所有列完全相同的重复行,保留第一次出现的 df_unique = df.drop_duplicates() # 基于某几列(如‘用户ID‘和‘日期‘)判断重复,并删除 df_unique = df.drop_duplicates(subset=[‘用户ID‘, ‘日期‘]) # 基于某几列判断重复,但保留最后一次出现的记录 df_unique = df.drop_duplicates(subset=[‘用户ID‘, ‘日期‘], keep=‘last‘)

4.3 数据类型转换与标准化

数据读入时,pandas会自动推断类型,但有时会出错(比如把本该是字符串的ID列推断成数字)。使用df[‘列名‘].astype(‘新类型‘)进行转换。

# 将‘用户ID‘列从浮点数转换为整数(先处理NaN,因为int不能有NaN) df[‘用户ID‘] = df[‘用户ID‘].fillna(0).astype(‘int64‘) # 将‘日期‘列从字符串转换为datetime类型,这是时间序列分析的前提 df[‘日期‘] = pd.to_datetime(df[‘日期‘], format=‘%Y-%m-%d‘) # 指定格式能加速转换 # 将分类文本列转换为category类型,能大幅节省内存和提高分组速度 df[‘城市‘] = df[‘城市‘].astype(‘category‘)

字符串列的标准化:对于文本数据,经常需要统一格式。

# 将所有城市名转换为小写并去除首尾空格 df[‘城市‘] = df[‘城市‘].str.lower().str.strip() # 将‘姓名‘列拆分成‘姓‘和‘名‘两列(假设用空格分隔) df[[‘姓‘, ‘名‘]] = df[‘姓名‘].str.split(‘ ‘, expand=True)

5. 数据选择、筛选与索引操作

高效、准确地选取目标数据是分析的基础。pandas提供了多种索引方式,理解它们的区别至关重要。

5.1 基础索引:[],.loc,.iloc

  • [](方括号):主要用于列选择

    # 选择单列,返回一个Series age_series = df[‘年龄‘] # 选择多列,返回一个DataFrame subset_df = df[[‘姓名‘, ‘年龄‘]]
  • .loc[]:基于标签进行选择。接受行标签和列标签。

    # 选择索引标签为2的行 df.loc[2] # 选择索引标签从1到3的行(包含3!) df.loc[1:3] # 选择索引标签为2的行,以及‘姓名‘和‘城市‘列 df.loc[2, [‘姓名‘, ‘城市‘]] # 选择所有行,但只取‘年龄‘列(效果同df[‘年龄‘],但这是.loc的用法) df.loc[:, ‘年龄‘]
  • .iloc[]:基于整数位置进行选择。接受行号和列号(从0开始)。

    # 选择第2行(第3行,因为从0开始) df.iloc[2] # 选择第1行到第3行(不包含第4行,这是Python切片惯例) df.iloc[1:4] # 选择第2行,第0列和第2列 df.iloc[2, [0, 2]]

核心避坑点.loc的切片是闭区间[start:end],而.iloc的切片是开区间[start:end),和Python列表切片一致。混淆这一点是常见错误源。

5.2 布尔索引:强大的条件筛选

这是最常用、最灵活的数据筛选方式。原理是:先创建一个布尔值Series(True/False),然后用这个Series去索引DataFrame。

# 筛选出年龄大于30的行 df[df[‘年龄‘] > 30] # 筛选出城市为‘北京‘或‘上海‘的行。注意要用 | (或) 和 & (与) 运算符,并且每个条件要用括号括起来。 df[(df[‘城市‘] == ‘北京‘) | (df[‘城市‘] == ‘上海‘)] # 筛选出年龄在25到35之间(包含)的行 df[(df[‘年龄‘] >= 25) & (df[‘年龄‘] <= 35)] # 使用.isin()方法简化多值筛选 df[df[‘城市‘].isin([‘北京‘, ‘上海‘, ‘广州‘])] # 筛选出‘姓名‘列包含‘张‘字的行 df[df[‘姓名‘].str.contains(‘张‘)] # 结合多个条件进行复杂筛选 df[(df[‘年龄‘] > 25) & (df[‘城市‘].isin([‘北京‘, ‘深圳‘])) & (~df[‘姓名‘].str.startswith(‘李‘))] # ~表示取反

5.3 处理SettingWithCopyWarning警告

这是一个让无数pandas初学者头疼的警告。它通常在你尝试修改一个可能是原始DataFrame子集的副本时出现。

# 危险操作:可能触发警告 subset = df[df[‘年龄‘] > 30] subset[‘新列‘] = 1 # 这行可能产生SettingWithCopyWarning

为什么?因为df[df[‘年龄‘] > 30]返回的可能是一个视图(view),也可能是一个副本(copy),pandas不确定。直接修改subset可能会也可能不会修改原始的df,这种不确定性是危险的。

解决方案

  1. 明确使用.copy()创建副本:如果你只是想基于筛选结果创建一个新的、独立的DataFrame并进行修改,与原始df无关。
    subset = df[df[‘年龄‘] > 30].copy() subset[‘新列‘] = 1 # 安全,不会警告,也不会影响原始df
  2. 使用.loc进行原地修改:如果你就是想修改原始df中满足条件的那些行。
    df.loc[df[‘年龄‘] > 30, ‘新列‘] = 1 # 安全,明确指定了修改的位置

养成习惯:要么用.copy(),要么用.loc赋值,可以避免99%的这类问题。

6. 数据变形与多表操作

6.1 行列转换与透视表

增加/删除列

# 直接赋值增加新列 df[‘年薪‘] = df[‘月薪‘] * 12 # 使用assign方法,它返回一个新的DataFrame,不影响原df(函数式编程风格) df_new = df.assign(年薪=lambda x: x[‘月薪‘] * 12, 是否高薪=lambda x: x[‘年薪‘] > 200000) # 删除列 df = df.drop(columns=[‘临时列‘, ‘旧列‘]) # 或 df.drop([‘临时列‘], axis=1, inplace=True)

行列转置df.T,将行变成列,列变成行。

透视表(pivot_table):这是数据分析的利器,用于对数据进行多维汇总。

# 假设df有‘日期‘、‘城市‘、‘产品‘、‘销售额‘四列 # 计算每个城市、每个产品的平均销售额 pivot = pd.pivot_table(df, values=‘销售额‘, index=‘城市‘, # 行分组 columns=‘产品‘, # 列分组 aggfunc=‘mean‘, # 聚合函数,也可以是‘sum‘, ‘count‘等 fill_value=0) # 填充缺失值为0 print(pivot)

6.2 数据合并与连接:concat,merge,join

这是处理多表数据的核心。

  • pd.concat():主要用于沿轴(行或列)简单堆叠多个结构相似的DataFrame。

    # 纵向堆叠(增加行) df_all = pd.concat([df1, df2, df3], ignore_index=True) # ignore_index重置索引 # 横向拼接(增加列),要求有相同的索引 df_wide = pd.concat([df_a, df_b], axis=1)
  • pd.merge():类似于SQL的JOIN操作,根据一个或多个键将不同DataFrame中的行连接起来。这是最常用、功能最强大的合并方法。

    # 假设df1有[‘ID‘, ‘Name‘], df2有[‘ID‘, ‘Score‘] # 内连接(inner join):只保留两个表都有的ID df_inner = pd.merge(df1, df2, on=‘ID‘, how=‘inner‘) # 左连接(left join):以左表df1为准,保留所有行,右表没有的匹配项填NaN df_left = pd.merge(df1, df2, on=‘ID‘, how=‘left‘) # 外连接(outer join):保留所有行,缺失值填NaN df_outer = pd.merge(df1, df2, on=‘ID‘, how=‘outer‘) # 根据多个键连接 df_multi = pd.merge(df1, df2, on=[‘ID‘, ‘Date‘], how=‘inner‘) # 左右表键名不同时使用left_on和right_on df_diff_key = pd.merge(df1, df2, left_on=‘ID_left‘, right_on=‘ID_right‘, how=‘inner‘)
  • .join()方法:是merge的简化版,主要用于基于索引的合并。

    # 将df2合并到df1的右侧,基于索引 df_joined = df1.join(df2, how=‘left‘)

实操心得:mergehow参数(连接方式)选择是关键。‘inner‘最常用,它只保留有关联的数据,能保证合并后数据的完整性。‘left‘当你需要保留主表(左表)全部记录时使用。合并后,务必检查行数是否符合预期,并用df.isnull().sum()检查右表字段的缺失情况,这能帮你发现数据关联中的问题。

6.3 分组聚合(GroupBy):数据分析的灵魂

GroupBy操作遵循“拆分-应用-合并”模式,是汇总分析的核心。

# 按‘城市‘分组,并计算每组的平均年龄 grouped = df.groupby(‘城市‘)[‘年龄‘].mean() # 按‘城市‘和‘性别‘进行多级分组,并计算每组的数量和平均薪资 grouped_complex = df.groupby([‘城市‘, ‘性别‘]).agg({ ‘用户ID‘: ‘count‘, # 计数 ‘月薪‘: ‘mean‘, # 平均 ‘月薪‘: [‘min‘, ‘max‘, ‘std‘] # 同时计算多个聚合指标 }) print(grouped_complex)

agg(aggregate)函数非常强大,可以传入自定义函数:

# 计算每个城市薪资的90分位数 def pct90(series): return series.quantile(0.9) df.groupby(‘城市‘)[‘月薪‘].agg(pct90)

重置索引:分组聚合后的结果,分组键会变成索引。使用reset_index()可以将其变回普通列。

summary_df = df.groupby(‘城市‘)[‘月薪‘].mean().reset_index(name=‘平均月薪‘) # 重命名聚合列

7. 时间序列数据处理

pandas对时间序列的支持是其杀手锏之一。将日期列转换为datetime类型后,你可以进行各种强大的操作。

7.1 时间解析与属性提取

# 转换日期列 df[‘日期‘] = pd.to_datetime(df[‘日期‘]) # 提取日期组件 df[‘年份‘] = df[‘日期‘].dt.year df[‘月份‘] = df[‘日期‘].dt.month df[‘星期几‘] = df[‘日期‘].dt.dayofweek # 周一=0, 周日=6 df[‘季度‘] = df[‘日期‘].dt.quarter # 计算时间差 df[‘天数差‘] = (df[‘日期‘] - pd.Timestamp(‘2023-01-01‘)).dt.days

7.2 重采样(Resampling)与滚动窗口

重采样用于将时间序列从一个频率转换到另一个频率(如将每日数据聚合为每月数据)。

# 假设df以‘日期‘为索引,且是每日数据 df = df.set_index(‘日期‘) # 按月度重采样,计算每月销售额的总和 monthly_sales = df[‘销售额‘].resample(‘M‘).sum() # ‘M‘: 月末, ‘MS‘: 月初 # 按周重采样,计算每周的平均值 weekly_avg = df[‘销售额‘].resample(‘W‘).mean()

滚动窗口计算用于计算移动平均值、移动标准差等,可以平滑时间序列数据。

# 计算7天的移动平均销售额 df[‘7天移动平均‘] = df[‘销售额‘].rolling(window=7).mean() # 计算30天的移动总和,并设置最小窗口数为1(即使数据不足30天也从第一天开始算) df[‘30天移动总和‘] = df[‘销售额‘].rolling(window=30, min_periods=1).sum()

8. 性能优化与高效操作

当数据量变大时,一些不当操作会成为性能瓶颈。

8.1 避免循环,使用向量化操作

这是pandas的第一性能铁律。永远不要用Python的for循环去遍历DataFrame的行。

慢(错误示范)

for i in range(len(df)): df.loc[i, ‘新列‘] = df.loc[i, ‘旧列‘] * 2

快(向量化)

df[‘新列‘] = df[‘旧列‘] * 2 # pandas底层用NumPy数组计算,速度极快

对于复杂的、无法直接向量化的行级操作,可以使用.apply()方法,但它的速度也比循环快得多,比向量化慢。

# 对‘姓名‘列的每个元素应用一个函数 df[‘姓名长度‘] = df[‘姓名‘].apply(len) # 对每一行应用一个函数(axis=1) def calculate_bonus(row): if row[‘绩效‘] > 90: return row[‘月薪‘] * 0.2 else: return row[‘月薪‘] * 0.1 df[‘奖金‘] = df.apply(calculate_bonus, axis=1)

对于更复杂的条件判断,np.wherenp.select是比.apply更快的向量化选择。

8.2 选择合适的数据类型

使用df.info()查看内存使用。将文本列转换为category类型,如果唯一值数量远小于总行数,可以节省大量内存。

df[‘城市‘] = df[‘城市‘].astype(‘category‘)

对于整数列,如果数值范围有限,可以使用更小的整数类型,如‘int8‘,‘int16‘,‘int32‘

8.3 使用查询(Query)方法

对于复杂的布尔筛选,使用df.query()方法有时更清晰,并且在某些情况下性能略优。

# 等价于 df[(df[‘年龄‘] > 25) & (df[‘城市‘].isin([‘北京‘, ‘上海‘]))] df_filtered = df.query(‘年龄 > 25 and 城市 in [“北京“, “上海“]‘)

9. 常见问题与排查技巧实录

在实际操作中,你一定会遇到各种报错和意外情况。这里记录了几个最高频的问题和我的解决思路。

问题1:KeyErrorwhen using.locor[]

  • 现象df.loc[‘some_label‘]df[‘some_column‘]报错KeyError
  • 排查
    1. 检查标签或列名是否拼写错误(大小写、空格)。
    2. 使用df.columnsdf.index确认该标签/列名确实存在。
    3. 对于.loc,确认你传入的是标签(label),而不是位置整数(应该用.iloc)。
  • 解决:修正拼写,或使用df.get(‘column‘, default=None)安全地获取列(不存在则返回默认值)。

问题2:SettingWithCopyWarning警告

  • 现象:如前所述,尝试修改切片或筛选后的数据时出现警告。
  • 解决:明确你的意图。如果是要修改原数据,使用.loc索引赋值。如果是想创建一个独立副本进行操作,就在链式操作末尾加上.copy()

问题3:合并(merge)后数据行数异常增多

  • 现象:两个小表合并后,行数变得巨大,远超预期。
  • 原因:这是“多对多”合并的典型症状。左表和右表的连接键(on)列中都有重复值,导致笛卡尔积。
  • 排查:合并前,检查连接键的唯一性。
    print(df1[‘ID‘].duplicated().any()) # 检查是否有重复ID print(df1[‘ID‘].nunique(), len(df1)) # 唯一ID数 vs 总行数
  • 解决:根据业务逻辑,决定是否需要先对数据进行去重或聚合,确保连接键在至少一张表中是唯一的。

问题4:读取文件时内存不足

  • 现象:读取大CSV或Excel文件时程序崩溃或报内存错误。
  • 解决策略
    1. 指定数据类型:在read_csv时用dtype参数指定每列类型,避免pandas用高内存类型(如object)推断低内存需求的数据(如小整数)。
    2. 只读需要的列:使用usecols参数。
    3. 分块读取:使用chunksize参数,迭代处理。
      chunk_iter = pd.read_csv(‘huge.csv‘, chunksize=100000) for chunk in chunk_iter: process(chunk) # 你的处理函数
    4. 使用更高效的数据格式:考虑将数据存储为Parquet或Feather格式,它们读写更快、更省空间。

问题5:分组(groupby)或透视(pivot)后结果混乱

  • 现象:分组后的数据不是预期的结构,或者聚合值全是NaN。
  • 排查
    1. 检查分组键列中是否有NaN。NaN会被单独分成一组,可能导致意外结果。考虑先用fillna处理。
    2. 检查聚合列的数据类型。对非数值列进行summean等操作会得到NaN。
    3. 对于透视表,检查valuesindexcolumns参数是否指定正确,aggfunc是否适合该列数据。

处理pandas问题的核心是理解你的数据理解每个操作的含义。遇到报错,先仔细阅读错误信息,它通常会指向问题所在。多用df.head()df.info()df.describe()来观察数据在每一步操作后的变化,这是最有效的调试手段。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询