当前位置: 代码网 > it编程>前端脚本>Python > 20个Python中pandas数据处理的高级技巧

20个Python中pandas数据处理的高级技巧

2025年06月18日 Python 我要评论
引言在数据科学和数据分析领域,python的pandas库已经成为处理结构化数据的标准工具。虽然许多数据科学家和分析师都熟悉pandas的基本操作,但该库中隐藏着许多强大的高级功能,可以显著提高数据处

引言

在数据科学和数据分析领域,python的pandas库已经成为处理结构化数据的标准工具。虽然许多数据科学家和分析师都熟悉pandas的基本操作,但该库中隐藏着许多强大的高级功能,可以显著提高数据处理的效率和灵活性。本文将介绍20个pandas高级技巧,帮助你提升数据处理和分析的能力,让你的代码更加简洁、高效且专业。

1. 高效数据读取与导出

技巧1:使用适当的数据类型

在读取大型数据集时,指定正确的数据类型可以显著减少内存使用并提高性能:

import pandas as pd
import numpy as np

# 定义数据类型字典
dtypes = {
    'id': np.int32,
    'numeric_col': np.float32,
    'category_col': 'category'
}

# 读取时指定数据类型
df = pd.read_csv('large_file.csv', dtype=dtypes)

技巧2:分块读取大文件

处理超大文件时,可以使用分块读取避免内存溢出:

chunks = []
for chunk in pd.read_csv('huge_file.csv', chunksize=100000):
    # 对每个块进行处理
    processed_chunk = some_processing_function(chunk)
    chunks.append(processed_chunk)

# 合并所有处理过的块
result = pd.concat(chunks)

技巧3:高效导出数据

导出大型dataframe时,可以使用更高效的方法:

# 使用apache parquet格式保存数据(需要安装pyarrow)
df.to_parquet('data.parquet', engine='pyarrow', compression='snappy')

# 使用hdf5格式(需要安装tables)
df.to_hdf('data.h5', key='df', mode='w')

技巧4:使用sql查询读取数据

直接从数据库使用sql查询读取数据:

import sqlite3

conn = sqlite3.connect('database.db')
df = pd.read_sql_query("select * from table where column > 5", conn)
conn.close()

2. 数据转换与重塑

技巧5:使用melt和pivot进行数据重塑

将宽格式数据转换为长格式,反之亦然:

# 宽格式转长格式
long_df = pd.melt(
    wide_df, 
    id_vars=['id', 'name'], 
    value_vars=['score1', 'score2', 'score3'],
    var_name='test',
    value_name='score'
)

# 长格式转宽格式
wide_df = long_df.pivot(
    index='id',
    columns='test',
    values='score'
).reset_index()

技巧6:使用explode展开列表值

将包含列表的单元格展开为多行:

df = pd.dataframe({
    'a': [[1, 2, 3], [4, 5], [6]],
    'b': ['a', 'b', 'c']
})

# 展开a列
exploded_df = df.explode('a')

技巧7:使用stack和unstack进行多级索引转换

处理多级索引数据:

# 将列索引转为行索引的一部分
stacked = df.stack()

# 将行索引的一部分转为列索引
unstacked = stacked.unstack()

技巧8:使用map、apply和applymap进行数据转换

不同粒度的数据转换:

# 对series中的每个元素应用函数
df['category'] = df['category'].map({'a': 'group1', 'b': 'group2'})

# 对dataframe的每一行或每一列应用函数
df['total'] = df[['col1', 'col2']].apply(sum, axis=1)

# 对dataframe中的每个元素应用函数
df = df.applymap(lambda x: x.lower() if isinstance(x, str) else x)

3. 高级索引与选择

技巧9:使用.loc和.iloc进行精确索引

高效地选择数据:

# 基于标签的索引
subset = df.loc[df['age'] > 30, ['name', 'salary']]

# 基于位置的索引
first_five_rows_three_cols = df.iloc[0:5, 0:3]

# 混合索引
mixed_selection = df.loc[df['status'] == 'active', df.columns[2:5]]

技巧10:使用query方法进行高效过滤

使用字符串表达式过滤数据:

# 传统方法
filtered_df = df[(df['age'] > 30) & (df['salary'] > 50000)]

# 使用query方法(更易读且通常更快)
filtered_df = df.query('age > 30 and salary > 50000')

# 使用变量
min_age = 30
filtered_df = df.query('age > @min_age')

技巧11:使用where进行条件替换

基于条件替换值:

# 将不满足条件的值替换为nan
df_modified = df.where(df > 0)

# 将不满足条件的值替换为指定值
df_modified = df.where(df > 0, -1)

技巧12:使用mask进行条件替换

与where相反的操作:

# 将满足条件的值替换为nan
df_modified = df.mask(df < 0)

# 将满足条件的值替换为指定值
df_modified = df.mask(df < 0, 0)

4. 分组操作与聚合

技巧13:使用groupby的高级功能

超越基本分组聚合:

# 多列分组
result = df.groupby(['department', 'title']).agg({'salary': ['mean', 'median', 'std'], 'age': 'mean'})

# 使用自定义聚合函数
def iqr(x):
    return x.quantile(0.75) - x.quantile(0.25)

result = df.groupby('department').agg({'salary': [iqr, lambda x: x.max() - x.min()]})

# 使用命名聚合
result = df.groupby('department').agg(
    avg_salary=('salary', 'mean'),
    max_age=('age', 'max'),
    min_age=('age', 'min')
)

技巧14:使用transform进行组内转换

在不改变dataframe形状的情况下应用组级别的计算:

# 添加组平均值列
df['salary_group_mean'] = df.groupby('department')['salary'].transform('mean')

# 使用自定义转换函数
df['salary_normalized'] = df.groupby('department')['salary'].transform(lambda x: (x - x.mean()) / x.std())

# 计算组内排名
df['salary_rank'] = df.groupby('department')['salary'].transform('rank', method='dense')

技巧15:使用filter筛选组

基于组级别条件筛选数据:

# 仅保留平均工资超过50000的部门
high_paying_depts = df.groupby('department').filter(lambda x: x['salary'].mean() > 50000)

# 仅保留至少有10名员工的部门
large_depts = df.groupby('department').filter(lambda x: len(x) >= 10)

技巧16:使用pipe构建数据处理管道

创建可重用的数据处理流程:

def add_features(df):
    df['salary_to_age_ratio'] = df['salary'] / df['age']
    return df

def filter_outliers(df, column, lower=0.01, upper=0.99):
    lower_bound = df[column].quantile(lower)
    upper_bound = df[column].quantile(upper)
    return df[(df[column] >= lower_bound) & (df[column] <= upper_bound)]

# 构建处理管道
processed_df = (df
                .pipe(add_features)
                .pipe(filter_outliers, 'salary')
                .pipe(filter_outliers, 'age'))

5. 时间序列数据处理

技巧17:使用日期范围和频率

创建和操作日期序列:

# 创建日期范围
date_range = pd.date_range(start='2025-01-01', end='2025-12-31', freq='b')  # b表示工作日

​​​​​​​# 创建月末日期序列
month_ends = pd.date_range(start='2025-01-01', periods=12, freq='m')

# 创建季度日期
quarters = pd.date_range(start='2025-01-01', periods=4, freq='q')

技巧18:时间序列重采样

改变时间序列的频率:

# 将日数据聚合为月数据
monthly_data = daily_data.resample('m').mean()

# 将小时数据聚合为日数据,并使用不同的聚合方法
daily_stats = hourly_data.resample('d').agg({
    'temperature': 'mean',
    'humidity': 'mean',
    'rainfall': 'sum',
    'wind_speed': ['min', 'max', 'mean']
})

# 将低频数据转换为高频数据(向前填充)
hourly_data = daily_data.resample('h').ffill()

技巧19:时间序列滚动窗口计算

计算移动平均、累积和等:

# 7天移动平均
df['7d_moving_avg'] = df['value'].rolling(window=7).mean()

# 30天指数加权移动平均
df['30d_ewm'] = df['value'].ewm(span=30).mean()

# 累积计算
df['cumulative_sum'] = df['value'].cumsum()
df['cumulative_product'] = df['value'].cumprod()

# 使用自定义窗口函数
df['rolling_median'] = df['value'].rolling(window=7).apply(lambda x: np.median(x))

技巧20:时区处理

处理不同时区的数据:

# 将时间戳转换为时区感知
df['timestamp'] = pd.to_datetime(df['timestamp']).dt.tz_localize('utc')

# 转换时区
df['local_time'] = df['timestamp'].dt.tz_convert('asia/shanghai')

# 移除时区信息
df['naive_time'] = df['timestamp'].dt.tz_localize(none)

# 在不同时区之间进行日期比较
mask = (df['timestamp'] >= pd.timestamp('2025-01-01', tz='utc')) & \
       (df['timestamp'] <= pd.timestamp('2025-01-31', tz='utc'))
filtered_df = df[mask]

6. 性能优化技巧

技巧21:使用inplace=true减少内存使用

在适当的情况下原地修改数据:

# 不创建新的dataframe
df.fillna(0, inplace=true)
df.drop('unused_column', axis=1, inplace=true)
df.reset_index(inplace=true)

注意:虽然inplace=true可以减少内存使用,但在某些情况下可能会降低性能,并且使代码的流式处理变得困难。在现代pandas版本中,推荐的做法是避免使用inplace=true,而是使用方法链。

技巧22:使用numba加速自定义函数

对于计算密集型操作,使用numba可以显著提高性能:

import numba

@numba.jit(nopython=true)
def fast_calculation(array):
    result = np.zeros_like(array)
    for i in range(len(array)):
        result[i] = some_complex_math(array[i])
    return result

df['result'] = fast_calculation(df['value'].values)

技巧23:使用swifter并行处理

自动并行化pandas操作:

# 安装:pip install swifter
import swifter

# 替代普通的apply操作
df['result'] = df['complex_column'].swifter.apply(complex_function)

技巧24:使用eval和query进行高性能操作

对于大型dataframe,使用这些方法可以避免创建中间对象:

# 传统方式
df['c'] = df['a'] + df['b']
df = df[(df['a'] < 100) & (df['b'] > 50)]

# 高性能方式
df = df.eval('c = a + b')
df = df.query('a < 100 and b > 50')

7. 可视化增强

技巧25:使用内置样式

利用pandas的内置样式增强可视化效果:

# 设置绘图样式
plt.style.use('ggplot')

# 使用pandas内置绘图功能
df.plot(kind='bar', figsize=(12, 6))

# 使用多种图表类型
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
df.plot(kind='line', ax=axes[0, 0], title='line plot')
df.plot(kind='bar', ax=axes[0, 1], title='bar plot')
df.plot(kind='box', ax=axes[1, 0], title='box plot')
df.plot(kind='scatter', x='a', y='b', ax=axes[1, 1], title='scatter plot')

技巧26:使用styler美化dataframe显示

在jupyter notebook中美化dataframe的显示:

# 高亮最大值
styled_df = df.style.highlight_max(color='lightgreen')

# 根据条件设置样式
styled_df = df.style.applymap(lambda x: 'background-color: yellow' if x < 0 else '')

# 使用渐变颜色
styled_df = df.style.background_gradient(cmap='viridis')

# 格式化数值
styled_df = df.style.format({
    'a': '{:.2f}',
    'b': '{:+.2f}',
    'c': '{:.2%}'
})

技巧27:交互式可视化

结合其他库创建交互式可视化:

# 使用plotly(需要安装plotly)
import plotly.express as px
fig = px.line(df, x='date', y='value', color='category')
fig.show()

# 使用hvplot(需要安装hvplot和holoviews)
import hvplot.pandas
interactive_plot = df.hvplot.scatter(x='a', y='b', by='category', hover_cols=['c', 'd'])

8. 综合应用示例

下面我们通过一个综合示例,展示如何将这些高级技巧应用到实际数据分析中:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 1. 高效读取数据
sales_data = pd.read_csv('sales_data.csv', 
                         parse_dates=['date'],
                         dtype={'product_id': 'category', 'store_id': 'category'})

# 2. 数据转换
# 添加时间特征
sales_data['year'] = sales_data['date'].dt.year
sales_data['month'] = sales_data['date'].dt.month
sales_data['day_of_week'] = sales_data['date'].dt.dayofweek

# 3. 高级索引与过滤
# 使用query筛选数据
recent_sales = sales_data.query('date >= "2024-01-01" and revenue > 1000')

# 4. 分组操作与聚合
# 按产品和月份分组,计算多个统计量
monthly_stats = sales_data.groupby(['product_id', 'year', 'month']).agg(
    total_revenue=('revenue', 'sum'),
    avg_revenue=('revenue', 'mean'),
    total_units=('units', 'sum'),
    transaction_count=('transaction_id', 'nunique')
).reset_index()

# 5. 时间序列处理
# 将数据重采样为周频率
weekly_sales = sales_data.set_index('date').groupby('product_id')['revenue'].resample('w').sum()

# 计算移动平均
monthly_sales = sales_data.set_index('date')['revenue'].resample('m').sum()
monthly_sales_smoothed = monthly_sales.rolling(window=3).mean()

# 6. 性能优化
# 使用eval计算新列
sales_data = sales_data.eval('revenue_per_unit = revenue / units')

# 7. 可视化
plt.figure(figsize=(12, 6))
sns.lineplot(x=monthly_sales.index, y=monthly_sales.values, label='monthly sales')
sns.lineplot(x=monthly_sales_smoothed.index, y=monthly_sales_smoothed.values, label='3-month moving average')
plt.title('monthly sales trend with moving average')
plt.xlabel('date')
plt.ylabel('revenue')
plt.legend()
plt.tight_layout()
plt.show()

总结

掌握这些pandas高级技巧可以显著提高你的数据处理和分析效率。从高效的数据读取和导出,到复杂的数据转换、高级索引、分组聚合、时间序列处理、性能优化和可视化增强,这些技巧涵盖了数据科学工作流程的各个方面。

通过不断实践和应用这些技巧,你将能够编写更简洁、高效和专业的数据分析代码,从而更快地从数据中获取洞察。

以上就是20个python中pandas数据处理的高级技巧的详细内容,更多关于python pandas的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com