杰瑞科技汇

Python处理Dataframe有哪些高效技巧?

目录

  1. 准备工作:安装与导入
  2. 创建 DataFrame
  3. 查看数据
  4. 数据选择与过滤
  5. 数据清洗
  6. 数据操作
    • 添加/删除列
    • 排序
    • 分组聚合
  7. 数据合并
  8. 数据透视与重塑
  9. 数据导出与导入
  10. 实战案例:一个完整的数据处理流程

准备工作:安装与导入

你需要确保已经安装了 Pandas 和它的核心依赖 NumPy。

Python处理Dataframe有哪些高效技巧?-图1
(图片来源网络,侵删)
pip install pandas numpy

在 Python 脚本或 Jupyter Notebook 中,通常这样导入:

import pandas as pd
import numpy as np

创建 DataFrame

DataFrame 是一个二维的、带标签的、大小可变的数据结构,类似于 Excel 表格或 SQL 表。

从字典创建 这是最常见的方式,键是列名,值是列数据。

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

从 NumPy 数组创建 可以指定行索引和列索引。

Python处理Dataframe有哪些高效技巧?-图2
(图片来源网络,侵删)
data = np.random.rand(4, 3) # 4行3列的随机数
df_array = pd.DataFrame(data, 
                        index=['row1', 'row2', 'row3', 'row4'],
                        columns=['col_A', 'col_B', 'col_C'])
print(df_array)

查看数据

当你拿到一个 DataFrame 时,首先需要了解它的基本情况。

  • df.head(n): 查看前 n 行数据,默认是 5 行。
  • df.tail(n): 查看后 n 行数据。
  • df.info(): 查看 DataFrame 的整体信息,包括列名、非空值数量、数据类型和内存占用。这是最常用的信息查看方法!
  • df.describe(): 生成描述性统计信息,包括计数、均值、标准差、最小值、最大值等,主要用于数值型列。
  • df.shape: 返回一个元组,表示 DataFrame 的行数和列数。
  • df.columns: 返回列名列表。
  • df.index: 返回行索引列表。
# 假设使用上面创建的 df
print("--- 前3行 ---")
print(df.head(3))
print("\n--- 基本信息 ---")
df.info()
print("\n--- 描述性统计 ---")
print(df.describe())
print("\n--- 形状 (行, 列) ---")
print(df.shape)
print("\n--- 列名 ---")
print(df.columns)

数据选择与过滤

选择数据是数据分析的核心操作。

选择列

  • 使用列名字符串df['列名']df.列名 (如果列名没有空格且是合法的变量名)。
# 选择单列
name_series = df['姓名']
print(type(name_series)) # 返回的是一个 Series
# 选择多列
subset_df = df[['姓名', '薪资']] # 注意,这里需要用两层方括号,返回的是 DataFrame
print(subset_df)

选择行

  • 使用 .loc[]:基于进行选择。df.loc[行标签, 列标签]
  • 使用 .iloc[]:基于整数位置进行选择。df.iloc[行索引, 列索引]
# 使用 .loc
print("--- 使用 .loc 选择第一行 ---")
print(df.loc[0]) # 行标签是 0
print("\n--- 使用 .loc 选择第一行的'姓名'和'城市' ---")
print(df.loc[0, ['姓名', '城市']])
# 使用 .iloc
print("\n--- 使用 .iloc 选择第一行 ---")
print(df.iloc[0])
print("\n--- 使用 .iloc 选择第一行的'姓名'和'城市' ---")
print(df.iloc[0, [0, 2]]) # '姓名'在第0列,'城市'在第2列

条件过滤 (布尔索引)

这是最强大的过滤方式。

# 筛选年龄大于30的人
older_than_30 = df[df['年龄'] > 30]
print(older_than_30)
# 筛选城市是上海且薪资大于10000的人
shanghai_high_salary = df[(df['城市'] == '上海') & (df['薪资'] > 10000)]
print(shanghai_high_salary)
# 使用 | 表示 "或"
# 筛选年龄小于28或者城市是北京的人
young_or_beijing = df[(df['年龄'] < 28) | (df['城市'] == '北京')]
print(young_or_beijing)

数据清洗

真实世界的数据总是不完美的,清洗是必不可少的一步。

Python处理Dataframe有哪些高效技巧?-图3
(图片来源网络,侵删)

处理缺失值

  • df.isnull().sum(): 查看每列的缺失值数量。
  • df.dropna(): 删除含有缺失值的行或列。
  • df.fillna(value): 用指定的值填充缺失值。
# 创建一个有缺失值的 DataFrame
df_with_nan = df.copy()
df_with_nan.loc[1, '薪资'] = np.nan
df_with_nan.loc[3, '城市'] = None # Pandas 会将 None 自动识别为 NaN
print("--- 带有缺失值的 DataFrame ---")
print(df_with_nan)
print("\n--- 每列缺失值数量 ---")
print(df_with_nan.isnull().sum())
# 删除含有缺失值的行
df_dropped = df_with_nan.dropna()
print("\n--- 删除含有缺失值的行后 ---")
print(df_dropped)
# 用均值填充薪资的缺失值
mean_salary = df_with_nan['薪资'].mean()
df_filled = df_with_nan.fillna({'薪资': mean_salary})
print("\n--- 用均值填充薪资后 ---")
print(df_filled)

处理重复值

  • df.duplicated(): 检查是否有重复行。
  • df.drop_duplicates(): 删除重复行。
df_with_dup = df.append(df.loc[0]) # 添加一行重复数据
print("--- 带有重复行的 DataFrame ---")
print(df_with_dup)
print("\n--- 删除重复行后 ---")
print(df_with_dup.drop_duplicates())

数据操作

添加/删除列

  • 直接赋值df['新列名'] = ...
  • df.drop(): 删除列或行。axis=1 表示按列删除,axis=0 表示按行删除。
# 添加一个新列 '级别'
df['级别'] = ['初级', '高级', '中级', '专家']
print("--- 添加新列后 ---")
print(df)
# 删除 '城市' 列
df_dropped_col = df.drop('城市', axis=1)
print("\n--- 删除'城市'列后 ---")
print(df_dropped_col)

排序

  • df.sort_values(): 按值排序。
    • by: 指定排序列。
    • ascending=True/False: 升序或降序。
    • inplace=True/False: 是否在原 DataFrame 上修改。
# 按'年龄'降序排序
df_sorted = df.sort_values(by='年龄', ascending=False)
print("--- 按'年龄'降序排序 ---")
print(df_sorted)
# 按'薪资'升序,'年龄'降序排序(多级排序)
df_multi_sorted = df.sort_values(by=['薪资', '年龄'], ascending=[True, False])
print("\n--- 按'薪资'升序、'年龄'降序排序 ---")
print(df_multi_sorted)

分组聚合

这是数据分析的利器,类似于 SQL 的 GROUP BY

  • df.groupby('列名'): 按指定列进行分组。
  • ['列名'].agg(['函数1', '函数2']): 对分组后的数据应用聚合函数。
# 按'城市'分组,计算每个城市的平均薪资
city_avg_salary = df.groupby('城市')['薪资'].mean()
print("--- 各城市平均薪资 ---")
print(city_avg_salary)
# 按'城市'分组,计算薪资的总和和人数
city_stats = df.groupby('城市')['薪资'].agg(['sum', 'count'])
print("\n--- 各城市薪资总和与人数 ---")
print(city_stats)

数据合并

  • pd.concat(): 用于堆叠 DataFrame,可以按行或按列拼接。
  • pd.merge(): 用于数据库风格的合并,类似于 SQL 的 JOIN
# 创建两个 DataFrame
df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value1': [1, 2, 3, 4]})
df2 = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value2': [5, 6, 7, 8]})
# 按 行 堆叠
concat_df = pd.concat([df1, df2], axis=0)
print("--- 按 行 堆叠 ---")
print(concat_df)
# 按 列 合并 (类似 SQL 的 FULL OUTER JOIN)
merged_df = pd.merge(df1, df2, on='key', how='outer')
print("\n--- 按'key'列合并 (OUTER JOIN) ---")
print(merged_df)
# 按 列 合并 (类似 SQL 的 INNER JOIN)
merged_inner_df = pd.merge(df1, df2, on='key', how='inner')
print("\n--- 按'key'列合并 (INNER JOIN) ---")
print(merged_inner_df)

数据透视与重塑

  • df.pivot_table(): 创建数据透视表,非常方便进行交叉分析。
  • df.melt(): 将宽格式的数据“融化”成长格式。
# 创建一个适合透视的 DataFrame
sales_data = {
    '月份': ['一月', '一月', '一月', '二月', '二月', '二月'],
    '产品': ['A', 'B', 'C', 'A', 'B', 'C'],
    '销售额': [100, 150, 200, 120, 180, 210]
}
sales_df = pd.DataFrame(sales_data)
# 创建透视表:按月份和产品分组,计算销售额总和
pivot_table = sales_df.pivot_table(index='月份', columns='产品', values='销售额', aggfunc='sum')
print("--- 销售额透视表 ---")
print(pivot_table)
# 将宽格式融化成长格式
melted_df = pivot_table.reset_index().melt(id_vars='月份', var_name='产品', value_name='销售额')
print("\n--- 融化后的长格式数据 ---")
print(melted_df)

数据导出与导入

Pandas 支持多种格式的读写。

# 导出为 CSV 文件
df.to_csv('output.csv', index=False, encoding='utf-8-sig') # index=False 不写入行索引
# 从 CSV 文件导入
df_from_csv = pd.read_csv('output.csv')
print("--- 从 CSV 读取的数据 ---")
print(df_from_csv)
# 导出为 Excel 文件
df.to_excel('output.xlsx', sheet_name='员工信息', index=False)
# 从 Excel 文件导入
df_from_excel = pd.read_excel('output.xlsx', sheet_name='员工信息')
print("\n--- 从 Excel 读取的数据 ---")
print(df_from_excel)

实战案例:一个完整的数据处理流程

假设我们有一个销售数据文件 sales.csv如下:

Date,Product,Region,Sales,Units
2025-01-01,Apple,North,1000,100
2025-01-01,Apple,South,1200,120
2025-01-01,Banana,North,800,200
2025-01-01,Banana,South,900,225
2025-01-02,Apple,North,1100,110
2025-01-02,Apple,South,1300,130
2025-01-02,Banana,North,850,212
2025-01-02,Banana,South,950,237
2025-01-03,Apple,North,1050,105
2025-01-03,Apple,South,1250,125
2025-01-03,Banana,North,820,205
2025-01-03,Banana,South,980,245

目标

  1. 读取数据。
  2. 查看“香蕉”在“北部”地区的总销售额和平均销售额。
  3. 计算每个产品的平均单价 (Sales / Units)。
  4. 找出销售额最高的那一天。
# 1. 读取数据
sales_df = pd.read_csv('sales.csv')
print("--- 原始数据 ---")
print(sales_df.head())
# 2. 筛选香蕉在北部地区的销售数据
banana_north_sales = sales_df[(sales_df['Product'] == 'Banana') & (sales_df['Region'] == 'North')]
total_banana_north_sales = banana_north_sales['Sales'].sum()
avg_banana_north_sales = banana_north_sales['Sales'].mean()
print(f"\n--- 香蕉在北部地区的总销售额: {total_banana_north_sales}, 平均销售额: {avg_banana_north_sales:.2f} ---")
# 3. 计算每个产品的平均单价
sales_df['Unit_Price'] = sales_df['Sales'] / sales_df['Units']
avg_price_per_product = sales_df.groupby('Product')['Unit_Price'].mean()
print("\n--- 各产品平均单价 ---")
print(avg_price_per_product)
# 4. 找出销售额最高的那一天
max_sales_row = sales_df.loc[sales_df['Sales'].idxmax()]
print("\n--- 销售额最高的那一天 ---")
print(max_sales_row)

这个案例涵盖了读取、过滤、计算、分组和查找极值等核心操作,是 Pandas 应用的一个缩影。

掌握 Pandas DataFrame 是数据科学和分析的基石,建议你:

  1. 多动手实践:尝试用上面的例子操作你自己的数据。
  2. 查阅官方文档Pandas Documentation 是最权威、最全面的参考资料。
  3. 善用搜索引擎:遇到具体问题,直接搜索 "pandas how to do X" 通常能找到解决方案。

希望这份详细的指南能帮助你快速上手 Python DataFrame 处理!

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