狂野飙车6鸿蒙版
471.84M · 2025-10-31
在数据驱动的时代,结构化数据(如表格、CSV文件、数据库表)是分析决策的基础。Python的Pandas库凭借其直观的数据结构和强大的功能,成为处理这类数据的首选工具。本文将以真实场景为线索,通过代码示例和操作逻辑解析,带你掌握Pandas处理结构化数据的核心方法。
结构化数据的本质是二维表格,包含行(记录)和列(特征)。传统Excel虽能处理这类数据,但在自动化、大规模计算和复杂分析上存在局限。Pandas通过DataFrame和Series两种核心数据结构,将表格操作转化为编程逻辑,实现高效处理。
为什么高效?
真实数据常存储在CSV、Excel或数据库中。Pandas提供多种读取函数,核心参数如下:
import pandas as pd
# 读取CSV(处理中文编码和缺失值)
df_csv = pd.read_csv('sales_2025.csv', encoding='utf-8', na_values=['NA', 'NULL'])
# 读取Excel(指定工作表)
df_excel = pd.read_excel('financial_report.xlsx', sheet_name='Q1')
# 读取数据库(需安装SQLAlchemy)
from sqlalchemy import create_engine
engine = create_engine('postgresql://user:password@localhost:5432/sales_db')
df_db = pd.read_sql('SELECT * FROM orders WHERE date > "2025-01-01"', engine)
关键参数解析:
原始数据常包含缺失值、重复值和异常值。以电商用户数据为例:
data = {
'user_id': [101, 102, 103, 104, 105],
'age': [25, 30, None, 35, 200], # 200为异常值
'city': ['北京', '上海', '广州', '北京', '北京']
}
df = pd.DataFrame(data)
# 方法1:删除含缺失值的行
df_dropna = df.dropna(subset=['age'])
# 方法2:用中位数填充(对异常值更鲁棒)
median_age = df['age'].median()
df_fillna = df.fillna({'age': median_age})
# 方法3:前向填充(时间序列数据适用)
df_ffill = df.fillna(method='ffill')
选择依据:
# 基于IQR(四分位距)检测异常值
Q1 = df['age'].quantile(0.25)
Q3 = df['age'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 过滤异常值
df_clean = df[(df['age'] >= lower_bound) & (df['age'] <= upper_bound)]
逻辑:IQR方法通过统计分布界定合理范围,适用于非正态分布数据。
# 删除完全重复的行
df_dedup = df.drop_duplicates()
# 按特定列去重(如保留最新记录)
df['timestamp'] = pd.to_datetime(['2025-01-01', '2025-01-02', '2025-01-03', '2025-01-04', '2025-01-05'])
df_latest = df.sort_values('timestamp').drop_duplicates(subset=['user_id'], keep='last')
df['order_date'] = pd.to_datetime(df['order_date'], format='%Y-%m-%d')
# 提取日期特征(如月份、星期)
df['month'] = df['order_date'].dt.month
df['day_of_week'] = df['order_date'].dt.dayofweek # 0=周一, 6=周日
优化:转换后内存占用减少50%以上(字符串'2025-01-01'占更多字节)。
# 统一转为小写
df['city'] = df['city'].str.lower()
# 替换特定值
df['city'] = df['city'].replace({'shanghai': '上海', 'beijing': '北京'})
bins = [0, 18, 35, 60, 100]
labels = ['未成年', '青年', '中年', '老年']
df['age_group'] = pd.cut(df['age'], bins=bins, labels=labels)
# 假设存在'consumption'列
result = df.groupby('city').agg(
avg_age=('age', 'mean'),
total_consumption=('consumption', 'sum')
)
输出示例:
avg_age total_consumption
city
北京 28.5 150000
上海 32.0 200000
广州 30.0 180000
# 确保日期为索引
df.set_index('order_date', inplace=True)
# 按周重采样并求和
weekly_sales = df['sales'].resample('W').sum()
# 计算周环比增长率
weekly_sales_pct = weekly_sales.pct_change() * 100
可视化(需配合Matplotlib):
import matplotlib.pyplot as plt
weekly_sales.plot(kind='line', title='Weekly Sales Trend')
plt.ylabel('Sales Amount')
plt.show()
pivot_table = pd.pivot_table(
df,
values='sales',
index=df['order_date'].dt.month,
columns='city',
aggfunc='sum',
fill_value=0
)
输出示例:
city 北京 上海 广州
month
1 5000 6000 4500
2 5500 6200 4800
当数据量超过1GB时,需采用以下策略:
# 读取时指定列类型
dtype_spec = {
'user_id': 'int32',
'age': 'float32',
'city': 'category' # 分类变量转为category类型
}
df_optimized = pd.read_csv('large_data.csv', dtype=dtype_spec)
效果:内存占用减少60%以上。
chunk_size = 100000 # 每次读取10万行
results = []
for chunk in pd.read_csv('huge_data.csv', chunksize=chunk_size):
# 对每个数据块进行处理(如清洗、聚合)
chunk_clean = chunk.dropna(subset=['sales'])
results.append(chunk_clean.groupby('city')['sales'].sum())
# 合并结果
final_result = pd.concat(results).groupby(level=0).sum()
import dask.dataframe as dd
ddf = dd.read_csv('terabyte_data/*.csv') # 读取文件夹内所有CSV
result = ddf.groupby('city')['sales'].mean().compute() # .compute()触发计算
解决:
# 检查列名是否存在
print(df.columns.tolist())
# 统一列名大小写
df.columns = df.columns.str.lower()
# 错误方式(可能不生效)
df[df['age'] > 30]['city'] = '高龄用户'
# 正确方式:使用.loc或复制数据
df.loc[df['age'] > 30, 'city'] = '高龄用户'
# 或
subset = df[df['age'] > 30].copy()
subset['city'] = '高龄用户'
学习建议:
从实际项目入手(如分析个人消费记录),逐步掌握以下流程:
数据加载 → 清洗 → 转换 → 分析 → 可视化 → 优化。
Pandas的强大之处在于,它让数据分析从“手工操作”升级为“可复用的编程流程”,这正是数据驱动决策的基础。