杰瑞科技汇

Python DataFrame操作有哪些实用技巧?

目录

  1. 环境准备
  2. 创建 DataFrame
  3. 查看数据
  4. 数据选择与过滤
    • 选择列
    • 选择行
    • 结合条件选择
  5. 数据清洗
    • 处理缺失值
    • 处理重复数据
    • 数据类型转换
  6. 数据修改与新增
    • 新增列
    • 修改列名
    • 删除列/行
  7. 数据分组与聚合
  8. 数据合并
  9. 数据排序
  10. 数据统计与计算
  11. 时间序列操作
  12. 数据导出

环境准备

确保你已经安装了 Pandas 和 NumPy 库,如果没有,请使用 pip 安装:

Python DataFrame操作有哪些实用技巧?-图1
(图片来源网络,侵删)
pip install pandas numpy

然后在 Python 脚本或 Jupyter Notebook 中导入它们:

import pandas as pd
import numpy as np

创建 DataFrame

创建 DataFrame 的最常见方式是使用字典。

# 使用字典创建
data = {
    '姓名': ['张三', '李四', '王五', '赵六', '张三'],
    '年龄': [25, 30, 28, 35, 25],
    '城市': ['北京', '上海', '广州', '深圳', '北京'],
    '薪资': [8000, 12000, 10000, 15000, 8500]
}
df = pd.DataFrame(data)
print(df)

输出:

   姓名  年龄  城市    薪资
0  张三  25  北京   8000
1  李四  30  上海  12000
2  王五  28  广州  10000
3  赵六  35  深圳  15000
4  张三  25  北京   8500

查看数据

掌握如何快速查看数据是进行后续操作的基础。

# 查看前5行
print(df.head())
# 查看后3行
print(df.tail(3))
# 查看数据的行数和列数
print(df.shape)  # 输出: (5, 4)
# 查看列名
print(df.columns)
# 查看数据类型和内存信息
print(df.info())
# 查看数值型列的描述性统计
print(df.describe())

数据选择与过滤

这是最常用的操作之一。

选择列

# 选择单列,返回一个 Series
name_series = df['姓名']
print(type(name_series))
# 选择多列,返回一个新的 DataFrame
subset_df = df[['姓名', '薪资']]
print(subset_df)

选择行

主要通过 .loc[] (基于标签) 和 .iloc[] (基于整数位置) 来实现。

# 使用 .loc[] 选择行 (通过索引标签)
# 选择索引为 1 和 3 的行
print(df.loc[[1, 3]])
# 使用 .iloc[] 选择行 (通过整数位置)
# 选择第 2 行和第 4 行 (从0开始计数)
print(df.iloc[[1, 3]])
# 选择连续的行
print(df.iloc[0:3]) # 包含 0, 1, 2 行

结合条件选择 (非常强大!)

这是数据分析的精髓,通常使用布尔索引。

# 单条件:筛选年龄大于30的人
print(df[df['年龄'] > 30])
# 多条件:筛选年龄大于30且在北京的人
# 注意:括号和 & (与), | (或), ~ (非) 的使用
print((df['年龄'] > 30) & (df['城市'] == '北京')) # 先得到布尔 Series
print(df[(df['年龄'] > 30) & (df['城市'] == '北京')]) # 再用布尔 Series 筛选
# 使用 .query() 方法 (语法更清晰)
print(df.query('年龄 > 30 and 城市 == "北京"'))

数据清洗

真实世界的数据往往不完美,清洗是必要步骤。

处理缺失值

# 创建一个带有缺失值的 DataFrame
df_with_nan = df.copy()
df_with_nan.loc[2, '薪资'] = np.nan
df_with_nan.loc[4, '年龄'] = np.nan
print("原始数据:")
print(df_with_nan)
# 1. 检查缺失值
print(df_with_nan.isnull().sum())
# 2. 删除含有缺失值的行
df_dropped = df_with_nan.dropna()
print("\n删除缺失值后的数据:")
print(df_dropped)
# 3. 填充缺失值
# 用固定值填充
df_filled_const = df_with_nan.fillna(0)
# 用列的平均值填充
df_filled_mean = df_with_nan.fillna(df_with_nan['薪资'].mean())
print("\n用平均值填充薪资后的数据:")
print(df_filled_mean)

处理重复数据

# 检查重复行
print(df.duplicated())
# 删除重复行 (保留第一个出现的)
df_unique = df.drop_duplicates()
print(df_unique)
# 根据 '姓名' 和 '年龄' 判断是否重复
df_unique_subset = df.drop_duplicates(subset=['姓名', '年龄'])
print(df_unique_subset)

数据类型转换

# 查看当前数据类型
print(df.dtypes)
# 将 '年龄' 列从 int64 转为 float64
df['年龄'] = df['年龄'].astype('float64')
print(df.dtypes)
# 将 '薪资' 列格式化为货币字符串
df['薪资_格式化'] = df['薪资'].apply(lambda x: f"¥{x:,}")
print(df)

数据修改与新增

新增列

可以直接通过赋值操作来新增列。

# 基于现有列计算新增列
df['年薪'] = df['薪资'] * 12
# 使用 apply 函数对列进行复杂操作
df['等级'] = df['薪资'].apply(lambda x: '高' if x > 10000 else '中' if x > 5000 else '低')
print(df)

修改列名

# 修改单个列名
df.rename(columns={'姓名': '员工姓名'}, inplace=True)
# 修改多个列名
df.rename(columns={'年龄': '员工年龄', '城市': '所在城市'}, inplace=True)
print(df)

注意: inplace=True 会直接在原 DataFrame 上修改,不返回新对象,推荐不使用 inplace,而是将结果赋值给一个新变量,这样代码更清晰、可预测。

删除列/行

# 删除列
df = df.drop('年薪', axis=1) # axis=1 表示按列删除
# 删除行
df = df.drop(4, axis=0) # axis=0 表示按行删除,删除索引为 4 的行
print(df)

数据分组与聚合

这是从数据中提取洞察力的核心操作,类似于 SQL 的 GROUP BY

# 按 '城市' 分组,计算每个城市的平均薪资
avg_salary_by_city = df.groupby('所在城市')['薪资'].mean()
print(avg_salary_by_city)
# 按 '城市' 分组,计算多个聚合指标
agg_results = df.groupby('所在城市').agg(
    平均薪资=('薪资', 'mean'),
    最高薪资=('薪资', 'max'),
    人数=('员工姓名', 'count')
)
print(agg_results)

数据合并

当需要将多个 DataFrame 组合在一起时使用。

# 创建另一个 DataFrame
df_bonus = pd.DataFrame({
    '员工姓名': ['张三', '李四', '王五'],
    '奖金': [1000, 2000, 1500]
})
# 使用 merge 进行类似 SQL 的 JOIN 操作
# how='inner' 表示内连接 (只保留两个 DataFrame 都有的键)
df_merged = pd.merge(df, df_bonus, on='员工姓名', how='inner')
print(df_merged)

数据排序

# 按 '薪资' 降序排序
df_sorted = df.sort_values(by='薪资', ascending=False)
print(df_sorted)
# 先按 '城市' 升序,再按 '薪资' 降序排序
df_sorted_multi = df.sort_values(by=['所在城市', '薪资'], ascending=[True, False])
print(df_sorted_multi)

数据统计与计算

Pandas 提供了丰富的数学和统计函数。

# 计算总和
print(df['薪资'].sum())
# 计算相关系数矩阵
print(df.corr())
# 对列进行逐元素计算
df['薪资_增加10%'] = df['薪资'] * 1.1

时间序列操作

如果数据中包含时间戳,Pandas 的 DatetimeIndex 功能非常强大。

# 创建一个时间序列 DataFrame
date_rng = pd.date_range(start='2025-01-01', end='2025-01-05', freq='D')
df_ts = pd.DataFrame(date_rng, columns=['date'])
df_ts['data'] = np.random.randint(0, 100, size=(5))
# 将 'date' 列转为 datetime 类型
df_ts['date'] = pd.to_datetime(df_ts['date'])
# 将 'date' 设为索引
df_ts = df_ts.set_index('date')
print(df_ts)
# 按时间重采样 (从天重采样到周)
# 'W-MON' 表示每周一
df_resampled = df_ts.resample('W-MON').sum()
print(df_resampled)

数据导出

处理完的数据可以导出为各种格式。

# 导出为 CSV 文件
df.to_csv('output.csv', index=False, encoding='utf-8-sig') # index=False 不保存索引,utf-8-sig 解决Excel中文乱码
# 导出为 Excel 文件
df.to_excel('output.xlsx', sheet_name='员工信息', index=False)
# 导出为 HTML 文件
df.to_html('output.html')

总结与最佳实践

  1. 链式操作: Pandas 的方法大多返回一个新的 DataFrame,这使得链式操作非常方便,代码更简洁。

    # 不好的写法
    df1 = df.drop_duplicates()
    df1 = df1[df1['年龄'] > 25]
    df1 = df1.sort_values('薪资')
    # 好的链式写法
    (df.drop_duplicates()
        .query('年龄 > 25')
        .sort_values('薪资'))
  2. 避免循环: 尽量不要在 DataFrame 上使用 Python 的 for 循环来处理行,Pandas 的向量化操作(如 df.apply(), df[df['列名'] > 值], df.groupby())在底层使用 C 语言优化,速度要快几个数量级。

  3. 善用文档: 遇到任何不清楚的函数或参数,第一时间查阅 Pandas 官方文档,它是学习 Pandas 最权威的资源。

  4. 理解 .loc, .iloc, .at, .iat:

    • .loc: 基于标签,最常用,推荐使用。
    • .iloc: 基于整数位置,在明确知道行/列位置时使用。
    • .at: .loc 的快速版,用于访问单个标量值。
    • .iat: .iloc 的快速版,用于访问单个标量值。

掌握了以上这些操作,你就可以应对绝大多数的数据处理和分析任务了,祝你学习愉快!

分享:
扫描分享到社交APP
上一篇
下一篇