Python Pandas 简介
Pandas 是 Python 数据分析领域最重要的库之一,提供了高性能、易用的数据结构和数据分析工具。它建立在 NumPy 之上,为处理结构化数据提供了强大的功能。无论是数据清洗、转换、分析还是可视化的前期准备,Pandas 都是不可或缺的工具。
在现代数据科学工作流中,Pandas 扮演着数据处理的核心角色。它不仅能够处理各种格式的数据文件,还提供了丰富的数据操作方法,让复杂的数据处理任务变得简单高效。
核心数据结构
Series:一维数据结构
Series 是 Pandas 中的一维数据结构,类似于带标签的数组。每个 Series 都有一个索引(index)和对应的值(values)。
import pandas as pd
import numpy as np
# 创建 Series
data = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
print(data)
# 从字典创建 Series
dict_data = {'apple': 10, 'banana': 20, 'orange': 15}
series_from_dict = pd.Series(dict_data)
print(series_from_dict)DataFrame:二维数据结构
DataFrame 是 Pandas 的核心数据结构,可以理解为带标签的二维表格,类似于 Excel 表格或 SQL 表。
# 创建 DataFrame
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'Age': [25, 30, 35, 28],
'City': ['New York', 'London', 'Tokyo', 'Paris'],
'Salary': [50000, 60000, 70000, 55000]
}
df = pd.DataFrame(data)
print(df)
# 查看基本信息
print(df.info())
print(df.describe())数据读取与写入
读取各种格式的数据
Pandas 支持读取多种数据格式,这是数据分析工作的第一步。
# 读取 CSV 文件
df_csv = pd.read_csv('data.csv')
# 读取 Excel 文件
df_excel = pd.read_excel('data.xlsx', sheet_name='Sheet1')
# 读取 JSON 文件
df_json = pd.read_json('data.json')
# 读取 SQL 数据库
import sqlite3
conn = sqlite3.connect('database.db')
df_sql = pd.read_sql_query('SELECT * FROM table_name', conn)
# 设置读取参数
df_custom = pd.read_csv(
'data.csv',
sep=',', # 分隔符
header=0, # 标题行
index_col=0, # 索引列
encoding='utf-8', # 编码格式
na_values=['N/A', 'NULL'] # 空值标识
)数据写入
# 写入 CSV 文件
df.to_csv('output.csv', index=False)
# 写入 Excel 文件
df.to_excel('output.xlsx', sheet_name='Data', index=False)
# 写入 JSON 文件
df.to_json('output.json', orient='records')
# 写入数据库
df.to_sql('table_name', conn, if_exists='replace', index=False)数据选择与索引
基本选择操作
# 选择列
names = df['Name'] # 单列
subset = df[['Name', 'Age']] # 多列
# 选择行
first_row = df.iloc[0] # 按位置选择
named_row = df.loc[0] # 按标签选择
# 切片操作
first_three = df.iloc[0:3] # 前三行
age_salary = df.loc[:, 'Age':'Salary'] # 指定列范围条件筛选
# 单条件筛选
high_salary = df[df['Salary'] > 55000]
# 多条件筛选
young_high_earners = df[(df['Age'] < 30) & (df['Salary'] > 50000)]
# 使用 isin() 方法
cities = df[df['City'].isin(['New York', 'London'])]
# 字符串筛选
names_with_a = df[df['Name'].str.contains('a', case=False)]高级索引操作
# 设置索引
df_indexed = df.set_index('Name')
# 重置索引
df_reset = df_indexed.reset_index()
# 多级索引
df_multi = df.set_index(['City', 'Name'])
print(df_multi.loc['New York'])数据清洗与预处理
处理缺失值
# 创建包含缺失值的数据
data_with_na = {
'A': [1, 2, np.nan, 4, 5],
'B': [np.nan, 2, 3, 4, np.nan],
'C': [1, 2, 3, 4, 5]
}
df_na = pd.DataFrame(data_with_na)
# 检查缺失值
print(df_na.isnull().sum())
print(df_na.info())
# 删除缺失值
df_dropped = df_na.dropna() # 删除包含缺失值的行
df_dropped_cols = df_na.dropna(axis=1) # 删除包含缺失值的列
# 填充缺失值
df_filled = df_na.fillna(0) # 用0填充
df_filled_mean = df_na.fillna(df_na.mean()) # 用均值填充
df_filled_forward = df_na.fillna(method='ffill') # 前向填充数据类型转换
# 查看数据类型
print(df.dtypes)
# 转换数据类型
df['Age'] = df['Age'].astype('float64')
df['City'] = df['City'].astype('category')
# 转换日期时间
date_data = pd.DataFrame({
'date_string': ['2023-01-01', '2023-01-02', '2023-01-03']
})
date_data['date'] = pd.to_datetime(date_data['date_string'])重复值处理
# 检查重复值
print(df.duplicated().sum())
# 删除重复值
df_unique = df.drop_duplicates()
# 基于特定列删除重复值
df_unique_name = df.drop_duplicates(subset=['Name'])数据变换与操作
数据排序
# 按单列排序
df_sorted = df.sort_values('Age')
# 按多列排序
df_multi_sorted = df.sort_values(['City', 'Age'], ascending=[True, False])
# 按索引排序
df_index_sorted = df.sort_index()数据分组与聚合
# 基本分组
grouped = df.groupby('City')
# 聚合操作
city_stats = df.groupby('City').agg({
'Age': ['mean', 'min', 'max'],
'Salary': ['sum', 'mean']
})
# 自定义聚合函数
def salary_range(x):
return x.max() - x.min()
custom_agg = df.groupby('City')['Salary'].agg(salary_range)
# 多列分组
multi_group = df.groupby(['City', 'Age']).size()数据透视表
# 创建透视表
pivot_table = df.pivot_table(
values='Salary',
index='City',
columns='Age',
aggfunc='mean',
fill_value=0
)
# 复杂透视表
complex_pivot = df.pivot_table(
values=['Salary', 'Age'],
index='City',
aggfunc={'Salary': 'mean', 'Age': 'count'}
)字符串操作
Pandas 提供了强大的字符串处理功能,通过 .str 访问器可以对字符串列进行各种操作。
# 创建字符串数据
text_data = pd.DataFrame({
'names': [' Alice Smith ', 'bob jones', 'CHARLIE BROWN', 'diana_wilson'],
'emails': ['alice@email.com', 'bob@COMPANY.COM', 'charlie@test.org', 'diana@work.net']
})
# 字符串清理
text_data['names_clean'] = text_data['names'].str.strip().str.title()
text_data['emails_lower'] = text_data['emails'].str.lower()
# 字符串分割
text_data['first_name'] = text_data['names_clean'].str.split().str[0]
text_data['domain'] = text_data['emails_lower'].str.split('@').str[1]
# 字符串替换
text_data['names_formatted'] = text_data['names_clean'].str.replace('_', ' ')
# 正则表达式
text_data['has_number'] = text_data['names'].str.contains(r'\d')时间序列处理
# 创建时间序列数据
dates = pd.date_range('2023-01-01', periods=100, freq='D')
ts_data = pd.DataFrame({
'date': dates,
'value': np.random.randn(100).cumsum()
})
ts_data.set_index('date', inplace=True)
# 时间索引操作
print(ts_data['2023-01']) # 选择特定月份
print(ts_data.loc['2023-01-01':'2023-01-07']) # 日期范围
# 重采样
monthly_mean = ts_data.resample('M').mean()
weekly_sum = ts_data.resample('W').sum()
# 时间偏移
ts_data['value_lag1'] = ts_data['value'].shift(1)
ts_data['value_lead1'] = ts_data['value'].shift(-1)
# 滚动窗口
ts_data['rolling_mean'] = ts_data['value'].rolling(window=7).mean()
ts_data['expanding_mean'] = ts_data['value'].expanding().mean()数据合并与连接
DataFrame 合并
# 创建示例数据
df1 = pd.DataFrame({
'key': ['A', 'B', 'C'],
'value1': [1, 2, 3]
})
df2 = pd.DataFrame({
'key': ['A', 'B', 'D'],
'value2': [4, 5, 6]
})
# 内连接
inner_join = pd.merge(df1, df2, on='key', how='inner')
# 左连接
left_join = pd.merge(df1, df2, on='key', how='left')
# 外连接
outer_join = pd.merge(df1, df2, on='key', how='outer')
# 基于索引合并
df1_indexed = df1.set_index('key')
df2_indexed = df2.set_index('key')
index_join = df1_indexed.join(df2_indexed, how='outer')数据拼接
# 垂直拼接
df_concat_vertical = pd.concat([df1, df2], ignore_index=True)
# 水平拼接
df_concat_horizontal = pd.concat([df1, df2], axis=1)
# 带键拼接
df_concat_keys = pd.concat([df1, df2], keys=['first', 'second'])实战应用案例
案例1:销售数据分析
# 模拟销售数据
np.random.seed(42)
sales_data = pd.DataFrame({
'date': pd.date_range('2023-01-01', periods=365, freq='D'),
'product': np.random.choice(['A', 'B', 'C'], 365),
'region': np.random.choice(['North', 'South', 'East', 'West'], 365),
'sales': np.random.randint(100, 1000, 365),
'cost': np.random.randint(50, 500, 365)
})
# 计算利润
sales_data['profit'] = sales_data['sales'] - sales_data['cost']
# 按月汇总
sales_data['month'] = sales_data['date'].dt.to_period('M')
monthly_summary = sales_data.groupby('month').agg({
'sales': 'sum',
'profit': 'sum',
'cost': 'sum'
})
# 产品表现分析
product_performance = sales_data.groupby('product').agg({
'sales': ['sum', 'mean'],
'profit': ['sum', 'mean']
}).round(2)
# 地区销售对比
region_pivot = sales_data.pivot_table(
values='sales',
index='region',
columns='product',
aggfunc='sum',
fill_value=0
)案例2:客户数据清洗
# 模拟脏数据
customer_data = pd.DataFrame({
'customer_id': [1, 2, 3, 4, 5, 5], # 重复ID
'name': [' John Doe ', 'jane smith', 'BOB WILSON', None, 'Alice Brown', 'Alice Brown'],
'email': ['john@email.com', 'JANE@EMAIL.COM', 'bob@invalid', 'alice@email.com', 'alice@email.com', 'alice@email.com'],
'age': [25, 30, -5, 150, 28, 28], # 异常年龄
'registration_date': ['2023-01-01', '2023-02-15', '2023-03-20', '2023-04-10', '2023-05-05', '2023-05-05']
})
# 数据清洗流程
def clean_customer_data(df):
# 复制数据避免修改原始数据
cleaned_df = df.copy()
# 处理重复记录
cleaned_df = cleaned_df.drop_duplicates()
# 清理姓名
cleaned_df['name'] = cleaned_df['name'].str.strip().str.title()
# 标准化邮箱
cleaned_df['email'] = cleaned_df['email'].str.lower()
# 处理异常年龄
cleaned_df = cleaned_df[(cleaned_df['age'] >= 0) & (cleaned_df['age'] <= 120)]
# 转换日期
cleaned_df['registration_date'] = pd.to_datetime(cleaned_df['registration_date'])
# 验证邮箱格式
email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
cleaned_df = cleaned_df[cleaned_df['email'].str.match(email_pattern, na=False)]
return cleaned_df
cleaned_customers = clean_customer_data(customer_data)
print("清洗 前记录数:", len(customer_data))
print("清洗后记录数:", len(cleaned_customers))性能优化技巧
内存优化
# 查看内存使用
print(df.memory_usage(deep=True))
# 优化数据类型
def optimize_dtypes(df):
for col in df.columns:
if df[col].dtype == 'object':
# 尝试转换为category
if df[col].nunique() / len(df) < 0.5:
df[col] = df[col].astype('category')
elif df[col].dtype == 'int64':
# 优化整数类型
if df[col].min() >= 0:
if df[col].max() < 255:
df[col] = df[col].astype('uint8')
elif df[col].max() < 65535:
df[col] = df[col].astype('uint16')
return df
optimized_df = optimize_dtypes(df.copy())向量化操作
# 避免循环,使用向量化操作
# 错误方式
result = []
for index, row in df.iterrows():
result.append(row['Age'] * 2)
# 正确方式
result = df['Age'] * 2
# 使用 apply 进行复杂操作
def complex_calculation(row):
return row['Age'] * row['Salary'] / 1000
df['metric'] = df.apply(complex_calculation, axis=1)
# 使用 numpy 函数
df['log_salary'] = np.log(df['Salary'])与 TRAE IDE 的完美结合
在使用 Pandas 进行数据分析时,TRAE IDE 提供了强大的 AI 辅助功能,让数据分析工作更加高效:
智能代码补全
TRAE IDE 的 AI 引擎能够理解 Pandas 的 API 结构,提供精准的代码补全建议。当你输入 df. 时,IDE 会根据 DataFrame 的结构智能推荐最相关的方法。
代码优化建议
通过 TRAE IDE 的智能分析,你可以获得 Pandas 代码的性能优化建议。例如,IDE 会提示你将循环操作替换为向量化操作,或建议使用更高效的数据类型。
错误诊断与修复
当 Pandas 代码出现错误时,TRAE IDE 能够快速定位问题并提供修复建议。无论是数据类型不匹配、索引错误还是方法调用问题,AI 助手都能提供准确的解决方案。
最佳实践总结
代码组织
# 良好的代码结构
class DataProcessor:
def __init__(self, file_path):
self.df = pd.read_csv(file_path)
self.cleaned_df = None
def clean_data(self):
"""数据清洗"""
self.cleaned_df = self.df.copy()
# 清洗逻辑
return self
def analyze(self):
"""数据分析"""
if self.cleaned_df is None:
raise ValueError("请先进行数据清洗")
# 分析逻辑
return self.cleaned_df.describe()
def export(self, output_path):
"""导出结果"""
self.cleaned_df.to_csv(output_path, index=False)
# 使用链式调用
processor = DataProcessor('data.csv')
results = processor.clean_data().analyze()性能监控
import time
from functools import wraps
def timing_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} 执行时间: {end_time - start_time:.2f} 秒")
return result
return wrapper
@timing_decorator
def process_large_dataset(df):
return df.groupby('category').agg({'value': ['sum', 'mean', 'count']})错误处理
def safe_data_operation(df, operation):
try:
result = operation(df)
return result
except KeyError as e:
print(f"列不存在: {e}")
return None
except ValueError as e:
print(f"数值错误: {e}")
return None
except Exception as e:
print(f"未知错误: {e}")
return None
# 使用示例
result = safe_data_operation(df, lambda x: x.groupby('nonexistent_column').sum())总结
Pandas 是 Python 数据分析生态系统中的核心工具,掌握其常用方法对于数据科学工作者至关重要。本文详细介绍了 Pandas 的核心功能,从基础的数据结构到高级的数据操作技巧,并通过实战案例展示了如何在真实项目中应用这些知识。
结合 TRAE IDE 的 AI 辅助功能,你可以更高效地编写 Pandas 代码,快速解决数据处理中遇到的问题。无论是数据清洗、分析还是可视化准备,Pandas 都能为你提供强大的支持。
在实际工作中,建议遵循最佳实践,注重代码的可读性和性能,合理使用 Pandas 的各种功能来构建高效的数据处理流水线。随着经验的积累,你将能够更加熟练地运用 Pandas 解决复杂的数据分析问题。
(此内容由 AI 辅助生成,仅供参考)