Pandas
基础
核心对象
对象 | 维度 | 核心属性 | 关键语义 |
---|---|---|---|
Series | 1D | 值 + 索引(标签) | “带标签的列” |
DataFrame | 2D | 行索引 + 列索引 + 块(block) | “Excel 表 + SQL 表 + ndarray” |
Index | 任意维 | 不可变、可哈希、可切片 | 轴标签容器 |
底层设计
- BlockManager:列同类型连续存储 → NumPy 免拷贝视图
- DatetimeIndex / PeriodIndex:时间维度高效切片、对齐
- Categorical:低内存因子化
- ExtensionArray:支持自定义列类型(如 IPv4、Decimal)
函数
类别 | 常用函数/方法 |
---|---|
数据读取 | read_csv , read_excel , read_json , read_sql , read_html |
数据查看 | head , tail , info , describe , shape , columns , index |
数据选择 | loc , iloc , at , iat , filter , query |
数据清洗 | dropna , fillna , drop_duplicates , replace , drop |
数据转换 | astype , apply , map , applymap , rename , set_index , reset_index |
分组聚合 | groupby , agg , transform , pivot_table , crosstab |
合并连接 | merge , join , concat , append |
时间序列 | to_datetime , resample , rolling , shift , diff |
可视化 | plot , hist , boxplot , scatter |
输入输出 | to_csv , to_excel , to_json , to_sql , to_html |
函数 | 一行示例 | 场景 |
---|---|---|
apply | df['col'].apply(lambda x: x**2) | 任意转换 |
groupby | df.groupby('city')['sales'].sum() | 分组聚合 |
fillna | df.fillna(method='ffill') | 缺失值补齐 |
merge | pd.merge(df1, df2, on='key') | 多表连接 |
pivot_table | pd.pivot_table(df, values='sales', index='prod', columns='region') | 交叉汇总 |
value_counts | df['cat'].value_counts() | 频次分布 |
astype | df['col'] = df['col'].astype('int') | 类型转换 |
dropna | df.dropna(subset=['price']) | 清理无效行 |
sort_values | df.sort_values('date', ascending=False) | 排序 |
query | df.query('sales > 1000 & region=="East"') | 表达式筛选 |
数据结构创建
import pandas as pd
import numpy as np
# 创建Series
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s)
# 创建DataFrame
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David'],
'Age': [25, 30, 35, 40],
'City': ['NY', 'LA', 'Chicago', 'Miami']
}
df = pd.DataFrame(data)
print(df)
数据读取与写入
# 读取CSV
df = pd.read_csv('data.csv')
# 读取Excel
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
# 读取SQL数据库
from sqlalchemy import create_engine
engine = create_engine('sqlite:///mydatabase.db')
df = pd.read_sql('SELECT * FROM mytable', engine)
# 写入CSV
df.to_csv('output.csv', index=False)
# 写入Excel
df.to_excel('output.xlsx', sheet_name='Results')
数据查看与检查
# 查看前n行
df.head(3)
# 查看后n行
df.tail(2)
# 查看基本信息
df.info()
# 统计描述
df.describe()
# 查看形状
df.shape
# 查看列名
df.columns
# 查看索引
df.index
数据选择与切片
# 选择单列
df['Name']
# 选择多列
df[['Name', 'Age']]
# 按标签选择行
df.loc[0] # 第一行
df.loc[1:3] # 第二到第四行
# 按位置选择行
df.iloc[0] # 第一行
df.iloc[1:4] # 第二到第四行
# 布尔索引
df[df['Age'] > 30]
# 复杂条件
df[(df['Age'] > 25) & (df['City'] == 'NY')]
缺失值处理
# 检测缺失值
df.isnull()
# 填充缺失值
df.fillna(0) # 用0填充
df.fillna(method='ffill') # 前向填充
# 删除缺失值
df.dropna()
重复值处理
# 检测重复行
df.duplicated()
# 删除重复行
df.drop_duplicates()
数据转换
# 重命名列
df.rename(columns={'Age': 'Years'})
# 类型转换
df['Age'] = df['Age'].astype(float)
# 应用函数
df['Age'] = df['Age'].apply(lambda x: x + 1)
# 向量化操作
df['Age'] += 1
# 替换值
df['City'].replace({'NY': 'New York', 'LA': 'Los Angeles'})
数据分组与聚合
# 基本分组
grouped = df.groupby('City')
# 聚合函数
grouped['Age'].mean()
grouped['Age'].agg(['mean', 'min', 'max', 'count'])
# 多列分组
df.groupby(['City', 'Gender'])['Age'].mean()
# 透视表
pd.pivot_table(df, values='Age', index='City', columns='Gender', aggfunc='mean')
数据合并与连接
# 连接两个DataFrame
pd.concat([df1, df2])
# 数据库式连接
pd.merge(left_df, right_df, on='key')
pd.merge(left_df, right_df, left_on='lkey', right_on='rkey', how='inner')
pd.merge(left_df, right_df, how='outer')
时间序列处理
# 创建时间序列
date_rng = pd.date_range(start='2023-01-01', end='2023-01-10', freq='D')
ts = pd.Series(np.random.randn(len(date_rng)), index=date_rng)
# 时间重采样
ts.resample('W').mean()
# 移动窗口计算
ts.rolling(window=3).mean()
应用
销售数据分析
# 读取销售数据
sales = pd.read_csv('sales_data.csv')
# 数据清洗
sales['Date'] = pd.to_datetime(sales['Date'])
sales = sales.dropna(subset=['Amount'])
# 按产品类别分析
category_sales = sales.groupby('Category')['Amount'].sum().sort_values(ascending=False)
# 按月分析销售趋势
monthly_sales = sales.resample('M', on='Date')['Amount'].sum()
# 计算每个客户的购买频率
customer_analysis = sales.groupby('CustomerID').agg(
Total_Spent=('Amount', 'sum'),
Purchase_Count=('InvoiceID', 'nunique'),
Avg_Purchase=('Amount', 'mean')
)
股票数据分析
# 读取股票数据
stocks = pd.read_csv('stock_prices.csv', parse_dates=['Date'], index_col='Date')
# 计算每日收益率
stocks['Return'] = stocks['Close'].pct_change()
# 计算移动平均
stocks['MA50'] = stocks['Close'].rolling(window=50).mean()
stocks['MA200'] = stocks['Close'].rolling(window=200).mean()
# 计算波动率
stocks['Volatility'] = stocks['Return'].rolling(window=30).std() * np.sqrt(252)
# 相关性分析
correlation_matrix = stocks[['AAPL', 'MSFT', 'GOOGL']].corr()
客户流失预测(数据预处理)
# 读取客户数据
customers = pd.read_csv('customers.csv')
# 处理缺失值
customers['Age'].fillna(customers['Age'].median(), inplace=True)
customers['Income'].fillna(customers.groupby('Occupation')['Income'].transform('mean'), inplace=True)
# 特征工程
customers['Tenure'] = (pd.to_datetime('today') - pd.to_datetime(customers['Join_Date'])).dt.days
customers['Monthly_Spend_Ratio'] = customers['Monthly_Spend'] / customers['Income']
# 编码分类变量
customers = pd.get_dummies(customers, columns=['Occupation', 'Region'], drop_first=True)
# 准备机器学习数据
X = customers.drop('Churned', axis=1)
y = customers['Churned']
电商用户行为分析
# 读取用户行为日志
logs = pd.read_json('user_logs.json', lines=True)
# 转换时间戳
logs['timestamp'] = pd.to_datetime(logs['timestamp'], unit='ms')
# 提取特征
logs['hour'] = logs['timestamp'].dt.hour
logs['day_of_week'] = logs['timestamp'].dt.dayofweek
# 会话分割
logs['session_id'] = (logs['timestamp'].diff() > pd.Timedelta('30min')).cumsum()
# 会话分析
session_analysis = logs.groupby('session_id').agg(
duration=('timestamp', lambda x: (x.max() - x.min()).seconds),
page_views=('url', 'count'),
user_id=('user_id', 'first')
)
时间序列预测(ARIMA)
from statsmodels.tsa.arima.model import ARIMA
# 准备数据
air_passengers = pd.read_csv('air_passengers.csv', parse_dates=['Month'], index_col='Month')
# 拆分训练测试集
train = air_passengers[:'1959-12-01']
test = air_passengers['1960-01-01':]
# 拟合ARIMA模型
model = ARIMA(train, order=(2,1,1))
model_fit = model.fit()
# 预测
forecast = model_fit.forecast(steps=12)
大数据并行 ETL
需求:5 GB CSV → 分组聚合 → 内存不足 → Dask + Pandas 语法。
import dask.dataframe as dd
ddf = dd.read_csv('big.csv')
out = (ddf.groupby('client_id')
.agg({'amount': ['sum','mean']})
.compute()) # 触发并行
out.to_parquet('result.parquet')
文本列数字提取
需求:订单备注含金额,正则提取数字。
df = pd.DataFrame({'note':['满100减20','满200减50','无优惠']})
df['money'] = df['note'].str.extract(r'(\d+)').astype(float)
技巧
性能优化
# 使用向量化操作替代循环
df['new_col'] = df['col1'] * 2 + df['col2']
# 使用eval()进行高效计算
df.eval('result = col1 + col2 * 3', inplace=True)
# 使用类别数据类型节省内存
df['category_col'] = df['category_col'].astype('category')
# 分块处理大数据
chunk_size = 10000
for chunk in pd.read_csv('large_file.csv', chunksize=chunk_size):
process(chunk)
可视化集成
import matplotlib.pyplot as plt
# 直接绘制DataFrame
df.plot(kind='line', x='Date', y='Price')
plt.title('Price Trend')
plt.show()
# 箱线图
df.boxplot(column='Age', by='City')
plt.suptitle('')
plt.title('Age Distribution by City')
plt.show()
# 相关矩阵热力图
import seaborn as sns
corr = df.corr()
sns.heatmap(corr, annot=True)
plt.show()
实用技巧
# 多条件赋值
df.loc[(df['Age'] > 30) & (df['City'] == 'NY'), 'Status'] = 'Senior'
# 应用复杂函数
def complex_function(row):
if row['Age'] > 40 and row['Income'] > 100000:
return 'High Value'
else:
return 'Standard'
df['Segment'] = df.apply(complex_function, axis=1)
# 交叉表分析
pd.crosstab(df['City'], df['Gender'], values=df['Age'], aggfunc='mean')
# 样式化输出
(df.style
.background_gradient(cmap='Blues', subset=['Age'])
.format({'Income': '${:,.2f}'})
.bar(subset=['Score'], color='lightgreen'))
与NumPy集成
# DataFrame转NumPy数组
array = df.values
# NumPy数组转DataFrame
new_df = pd.DataFrame(array, columns=df.columns)
# 在Pandas中使用NumPy函数
df['log_income'] = np.log(df['Income'])
← Previous postPython框架Flask
Next post →Python类库Numpy