本文目录导读:

我来介绍如何使用Pandas构建数据管道函数,通过多个实践案例来说明。
基础数据管道结构
import pandas as pd
import numpy as np
from typing import List, Dict, Any, Callable
# 创建示例数据
def create_sample_data():
np.random.seed(42)
dates = pd.date_range('2023-01-01', periods=100, freq='D')
data = {
'date': dates,
'product': np.random.choice(['A', 'B', 'C', 'D'], 100),
'category': np.random.choice(['Electronics', 'Clothing', 'Food'], 100),
'quantity': np.random.randint(1, 100, 100),
'price': np.random.uniform(10, 1000, 100).round(2),
'customer_id': np.random.randint(1000, 2000, 100)
}
# 添加一些缺失值
data['quantity'][np.random.choice(100, 5)] = np.nan
data['price'][np.random.choice(100, 3)] = np.nan
return pd.DataFrame(data)
数据清理管道
def clean_pipeline(df: pd.DataFrame) -> pd.DataFrame:
"""
数据清理管道
"""
def remove_duplicates(data):
"""去重"""
return data.drop_duplicates()
def handle_missing_values(data):
"""处理缺失值"""
data = data.copy()
# 数值列用中位数填充
numeric_cols = data.select_dtypes(include=[np.number]).columns
for col in numeric_cols:
data[col] = data[col].fillna(data[col].median())
return data
def remove_outliers(data, columns: List[str], threshold: float = 3):
"""移除异常值"""
data = data.copy()
for col in columns:
z_scores = np.abs((data[col] - data[col].mean()) / data[col].std())
data = data[z_scores < threshold]
return data
return (df
.pipe(remove_duplicates)
.pipe(handle_missing_values)
.pipe(remove_outliers, columns=['quantity', 'price']))
特征工程管道
def feature_engineering_pipeline(df: pd.DataFrame) -> pd.DataFrame:
"""
特征工程管道
"""
def create_date_features(data):
"""创建日期特征"""
data = data.copy()
if 'date' in data.columns:
data['year'] = data['date'].dt.year
data['month'] = data['date'].dt.month
data['day'] = data['date'].dt.day
data['day_of_week'] = data['date'].dt.dayofweek
data['is_weekend'] = data['day_of_week'].isin([5, 6]).astype(int)
return data
def create_aggregate_features(data):
"""创建聚合特征"""
data = data.copy()
# 对每个产品计算历史统计
product_stats = data.groupby('product').agg({
'quantity': ['mean', 'std', 'max'],
'price': ['mean', 'std']
}).round(2)
# 展平列名
product_stats.columns = ['_'.join(col).strip() for col in product_stats.columns.values]
product_stats = product_stats.reset_index()
# 合并回原数据
data = data.merge(product_stats, on='product', how='left')
return data
def create_interaction_features(data):
"""创建交叉特征"""
data = data.copy()
data['total_value'] = data['quantity'] * data['price']
data['log_total_value'] = np.log1p(data['total_value'])
data['price_per_unit'] = data['price'] / data['quantity']
return data
return (df
.pipe(create_date_features)
.pipe(create_aggregate_features)
.pipe(create_interaction_features))
数据转换管道
def transformation_pipeline(df: pd.DataFrame) -> pd.DataFrame:
"""
数据转换管道
"""
def encode_categorical(data, method: str = 'onehot'):
"""编码分类变量"""
import warnings
warnings.filterwarnings('ignore')
data = data.copy()
categorical_cols = data.select_dtypes(include=['object']).columns
if method == 'label':
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
for col in categorical_cols:
data[f'{col}_encoded'] = le.fit_transform(data[col])
elif method == 'onehot':
data = pd.get_dummies(data, columns=categorical_cols, prefix=categorical_cols)
return data
def normalize_numeric(data, method: str = 'minmax'):
"""标准化数值"""
from sklearn.preprocessing import MinMaxScaler, StandardScaler
data = data.copy()
numeric_cols = data.select_dtypes(include=[np.number]).columns
scaler = MinMaxScaler() if method == 'minmax' else StandardScaler()
data[numeric_cols] = scaler.fit_transform(data[numeric_cols])
return data
return (df
.pipe(encode_categorical, method='onehot')
.pipe(normalize_numeric, method='standardize'))
完整的数据处理管道类
class DataPipeline:
"""
完整的数据管道类
"""
def __init__(self):
self.steps = []
self.logs = []
def add_step(self, name: str, func: Callable, **kwargs):
"""添加管道步骤"""
self.steps.append({
'name': name,
'function': func,
'kwargs': kwargs
})
return self
def run(self, df: pd.DataFrame) -> pd.DataFrame:
"""执行管道"""
result = df.copy()
for step in self.steps:
start_shape = result.shape
result = step['function'](result, **step['kwargs'])
end_shape = result.shape
self.logs.append({
'step': step['name'],
'start_shape': start_shape,
'end_shape': end_shape,
'changes': f"{(start_shape[0]-end_shape[0])} rows, {(start_shape[1]-end_shape[1])} cols"
})
return result
def summarize(self):
"""管道摘要"""
return pd.DataFrame(self.logs)
# 使用示例
def pipeline_example():
pipeline = DataPipeline()
pipeline.add_step('clean', clean_pipeline)
pipeline.add_step('features', feature_engineering_pipeline)
pipeline.add_step('transform', transformation_pipeline)
df = create_sample_data()
result = pipeline.run(df)
print("原始数据形状:", df.shape)
print("处理后数据形状:", result.shape)
print("\n管道执行日志:")
print(pipeline.summarize())
return result
# 执行管道
result = pipeline_example()
链式管道函数
class ChainPipe:
"""
链式管道实现
"""
def __init__(self, data: pd.DataFrame):
self.data = data
def filter(self, condition: Callable):
"""过滤数据"""
self.data = self.data[condition(self.data)]
return self
def select(self, columns: List[str]):
"""选择列"""
self.data = self.data[columns]
return self
def mutate(self, **kwargs):
"""创建新列"""
self.data = self.data.assign(**kwargs)
return self
def group_aggregate(self, group_cols: List[str], agg_dict: Dict):
"""分组聚合"""
self.data = self.data.groupby(group_cols).agg(agg_dict).reset_index()
return self
def sort(self, by: List[str], ascending: bool = True):
"""排序"""
self.data = self.data.sort_values(by=by, ascending=ascending)
return self
def get_data(self):
"""获取数据"""
return self.data
# 使用示例
def chain_pipeline_example():
df = create_sample_data()
pipeline = (ChainPipe(df)
.filter(lambda x: x['quantity'] > 10)
.filter(lambda x: x['price'] > 50)
.mutate(total = lambda x: x['quantity'] * x['price'])
.sort(by=['total'], ascending=False)
.select(['date', 'product', 'total'])
.get_data())
print("链式管道处理结果:")
print(pipeline.head(10))
return pipeline
# 执行
chain_pipeline_example()
异步数据管道
import asyncio
from concurrent.futures import ThreadPoolExecutor
class AsyncDataPipeline:
"""
异步数据管道
"""
def __init__(self, max_workers=4):
self.executor = ThreadPoolExecutor(max_workers=max_workers)
async def process_chunk(self, chunk: pd.DataFrame, functions: List[Callable]):
"""异步处理数据块"""
for func in functions:
chunk = await asyncio.get_event_loop().run_in_executor(
self.executor, func, chunk
)
return chunk
async def parallel_process(self, df: pd.DataFrame, functions: List[Callable], n_chunks: int = 4):
"""并行处理大数据集"""
chunks = np.array_split(df, n_chunks)
tasks = [self.process_chunk(chunk, functions) for chunk in chunks]
results = await asyncio.gather(*tasks)
return pd.concat(results, ignore_index=True)
# 异步管道使用
async def async_pipeline_example():
df = create_sample_data()
pipeline = AsyncDataPipeline()
functions = [clean_pipeline, feature_engineering_pipeline]
result = await pipeline.parallel_process(df, functions, n_chunks=2)
print(f"异步处理结果形状: {result.shape}")
return result
# 运行异步管道
async_pipeline_example()
实际应用案例:销售数据分析管道
def sales_analysis_pipeline(df: pd.DataFrame) -> Dict[str, Any]:
"""
销售分析完整管道
"""
def calculate_revenue(data):
"""计算收入"""
data['revenue'] = data['quantity'] * data['price']
return data
def analyze_performance(data):
"""分析表现"""
# 产品表现
product_performance = data.groupby('product').agg({
'revenue': 'sum',
'quantity': 'sum',
'customer_id': 'nunique'
}).round(2)
product_performance['avg_order_value'] = (
product_performance['revenue'] / product_performance['customer_id']
).round(2)
# 类别表现
category_performance = data.groupby('category').agg({
'revenue': ['sum', 'mean'],
'quantity': 'sum'
}).round(2)
return product_performance, category_performance
def find_top_customers(data, n: int = 10):
"""找出最佳客户"""
top_customers = (data.groupby('customer_id')
.agg({
'revenue': 'sum',
'quantity': 'sum',
'product': lambda x: x.mode().iloc[0] if not x.mode().empty else None
})
.nlargest(n, 'revenue')
.reset_index())
return top_customers
# 执行管道
df_clean = df.pipe(calculate_revenue)
product_perf, category_perf = analyze_performance(df_clean)
top_customers = find_top_customers(df_clean)
return {
'processed_data': df_clean,
'product_performance': product_perf,
'category_performance': category_perf,
'top_customers': top_customers
}
# 运行销售分析
df = create_sample_data()
results = sales_analysis_pipeline(df)
print("产品表现:")
print(results['product_performance'].head())
print("\n客户表现:")
print(results['top_customers'].head())
关键要点
- 管道模式优势:代码可复用、易于测试、流程清晰
- 函数组合:使用
.pipe()方法串联处理步骤 - 灵活配置:通过参数化函数适应不同需求
- 错误处理:添加适当的异常处理和日志记录
- 性能优化:大数据集考虑使用Dask或并行处理
这些管道函数可以根据具体需求进行调整和扩展,形成完整的数据处理工作流。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播