Python数据分析快速入门手册
目录
环境配置
推荐安装方式
# 安装Miniconda(轻量级Anaconda)
# 下载地址:https://docs.conda.io/en/latest/miniconda.html
# 或使用pip直接安装
pip install numpy pandas matplotlib seaborn jupyter scikit-learn
Jupyter Notebook使用
# 启动Jupyter
jupyter notebook
# 或在VSCode中直接使用
# 安装Python扩展和Jupyter扩展
Python基础
1. 基本数据类型
# 变量与基本类型
x = 10 # 整数
y = 3.14 # 浮点数
name = "数据分析" # 字符串
is_valid = True # 布尔值
# 列表(可变)
data_list = [1, 2, 3, 4, 5]
data_list.append(6)
# 元组(不可变)
data_tuple = (1, 2, 3)
# 字典
data_dict = {"name": "John", "age": 25, "city": "Beijing"}
# 集合
data_set = {1, 2, 3, 4, 5}
2. 控制流
# 条件判断
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
else:
grade = "C"
# 循环
# for循环
for i in range(5):
print(i)
# while循环
count = 0
while count < 5:
print(count)
count += 1
3. 函数定义
def calculate_mean(numbers):
"""计算平均值"""
return sum(numbers) / len(numbers)
# 使用lambda函数
square = lambda x: x ** 2
4. 列表推导式
# 简洁的列表创建方式
squares = [x**2 for x in range(10)]
even_numbers = [x for x in range(20) if x % 2 == 0]
数据分析核心库
1. NumPy - 数值计算基础
import numpy as np
# 创建数组
arr = np.array([1, 2, 3, 4, 5])
matrix = np.array([[1, 2, 3], [4, 5, 6]])
# 常用操作
zeros = np.zeros((3, 4)) # 3x4的零矩阵
ones = np.ones((2, 3)) # 2x3的全1矩阵
random_arr = np.random.rand(5) # 随机数组
# 数组运算
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
sum_arr = arr1 + arr2 # 对应元素相加
dot_product = np.dot(arr1, arr2) # 点积
# 统计函数
mean_value = np.mean(arr)
std_value = np.std(arr)
max_value = np.max(arr)
min_value = np.min(arr)
2. Pandas - 数据处理核心
import pandas as pd
# 创建DataFrame
data = {
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, 30, 35, 28],
'城市': ['北京', '上海', '广州', '深圳'],
'薪资': [5000, 8000, 6000, 7000]
}
df = pd.DataFrame(data)
# 基本操作
print(df.head()) # 查看前5行
print(df.info()) # 数据信息
print(df.describe()) # 统计描述
# 数据选择
df['年龄'] # 选择单列
df[['姓名', '薪资']] # 选择多列
df.iloc[0:3] # 按位置选择行
df.loc[df['年龄'] > 28] # 按条件选择
# 数据清洗
df.dropna() # 删除缺失值
df.fillna(0) # 填充缺失值
df.drop_duplicates() # 删除重复值
# 数据转换
df['薪资等级'] = df['薪资'].apply(lambda x: '高' if x > 7000 else '中' if x > 5500 else '低')
# 分组聚合
grouped = df.groupby('城市')['薪资'].agg(['mean', 'count', 'sum'])
数据可视化库
1. Matplotlib - 基础绘图
import matplotlib.pyplot as plt
import numpy as np
# 设置中文字体(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 折线图
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.figure(figsize=(10, 6))
plt.plot(x, y, label='sin(x)', color='blue', linewidth=2)
plt.title('正弦函数曲线')
plt.xlabel('X轴')
plt.ylabel('Y轴')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# 散点图
plt.figure(figsize=(8, 6))
plt.scatter(df['年龄'], df['薪资'], c='red', alpha=0.6)
plt.title('年龄与薪资关系')
plt.xlabel('年龄')
plt.ylabel('薪资')
plt.show()
# 柱状图
categories = ['A', 'B', 'C', 'D']
values = [23, 45, 56, 78]
plt.figure(figsize=(8, 6))
plt.bar(categories, values, color=['red', 'green', 'blue', 'orange'])
plt.title('分类数据柱状图')
plt.xlabel('类别')
plt.ylabel('数值')
plt.show()
# 直方图
data = np.random.randn(1000)
plt.figure(figsize=(8, 6))
plt.hist(data, bins=30, alpha=0.7, color='skyblue', edgecolor='black')
plt.title('数据分布直方图')
plt.xlabel('数值')
plt.ylabel('频率')
plt.show()
# 子图
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes[0, 0].plot(x, y)
axes[0, 0].set_title('子图1')
axes[0, 1].scatter(x, np.cos(x))
axes[0, 1].set_title('子图2')
axes[1, 0].bar(categories, values)
axes[1, 0].set_title('子图3')
axes[1, 1].hist(data, bins=20)
axes[1, 1].set_title('子图4')
plt.tight_layout()
plt.show()
2. Seaborn - 高级统计图表
import seaborn as sns
# 设置样式
sns.set_style("whitegrid")
sns.set_palette("husl")
# 加载示例数据
tips = sns.load_dataset("tips")
# 箱线图
plt.figure(figsize=(10, 6))
sns.boxplot(x='day', y='total_bill', data=tips)
plt.title('不同日期消费箱线图')
plt.show()
# 小提琴图
plt.figure(figsize=(10, 6))
sns.violinplot(x='day', y='total_bill', hue='sex', data=tips, split=True)
plt.title('消费分布小提琴图')
plt.show()
# 热力图
correlation = tips.corr()
plt.figure(figsize=(8, 6))
sns.heatmap(correlation, annot=True, cmap='coolwarm', center=0)
plt.title('相关性热力图')
plt.show()
# 分布图
plt.figure(figsize=(10, 8))
sns.jointplot(x='total_bill', y='tip', data=tips, kind='scatter')
plt.suptitle('消费与小费关系分布图')
plt.show()
# 配对图
sns.pairplot(tips, hue='sex', diag_kind='kde')
plt.suptitle('多变量配对图', y=1.02)
plt.show()
3. Plotly - 交互式图表
# 安装:pip install plotly
import plotly.express as px
import plotly.graph_objects as go
# 使用示例数据
df = px.data.gapminder().query("year == 2007")
# 散点图(交互式)
fig = px.scatter(df, x="gdpPercap", y="lifeExp",
size="pop", color="continent",
hover_name="country",
log_x=True, size_max=60,
title="2007年各国GDP与预期寿命")
fig.show()
# 3D散点图
fig = px.scatter_3d(df, x='gdpPercap', y='lifeExp', z='pop',
color='continent', hover_name='country')
fig.show()
实战案例
案例1:销售数据分析
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
# 创建模拟销售数据
np.random.seed(42)
dates = pd.date_range('2023-01-01', '2023-12-31', freq='D')
sales_data = pd.DataFrame({
'日期': dates,
'销售额': np.random.normal(10000, 2000, len(dates)),
'订单数': np.random.poisson(50, len(dates)),
'产品类别': np.random.choice(['电子产品', '服装', '食品', '家居'], len(dates)),
'客户类型': np.random.choice(['新客户', '老客户'], len(dates), p=[0.3, 0.7])
})
# 添加季节趋势
sales_data['销售额'] = sales_data['销售额'] * (1 + 0.3 * np.sin(2 * np.pi * sales_data['日期'].dt.dayofyear / 365))
print("数据概览:")
print(sales_data.head())
print("\n基本统计:")
print(sales_data.describe())
# 月度销售分析
sales_data['月份'] = sales_data['日期'].dt.month
monthly_sales = sales_data.groupby('月份')['销售额'].agg(['sum', 'mean', 'std'])
# 可视化
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 月度销售额趋势
axes[0, 0].plot(monthly_sales.index, monthly_sales['sum'], marker='o', linewidth=2)
axes[0, 0].set_title('月度销售额趋势')
axes[0, 0].set_xlabel('月份')
axes[0, 0].set_ylabel('销售额')
axes[0, 0].grid(True, alpha=0.3)
# 2. 产品类别销售额
category_sales = sales_data.groupby('产品类别')['销售额'].sum()
axes[0, 1].bar(category_sales.index, category_sales.values)
axes[0, 1].set_title('各产品类别销售额')
axes[0, 1].set_xlabel('产品类别')
axes[0, 1].set_ylabel('销售额')
axes[0, 1].tick_params(axis='x', rotation=45)
# 3. 销售额分布
axes[1, 0].hist(sales_data['销售额'], bins=30, alpha=0.7, color='skyblue', edgecolor='black')
axes[1, 0].set_title('销售额分布')
axes[1, 0].set_xlabel('销售额')
axes[1, 0].set_ylabel('频数')
# 4. 客户类型对比
customer_sales = sales_data.groupby('客户类型')['销售额'].agg(['mean', 'count'])
axes[1, 1].bar(customer_sales.index, customer_sales['mean'])
axes[1, 1].set_title('不同类型客户平均销售额')
axes[1, 1].set_xlabel('客户类型')
axes[1, 1].set_ylabel('平均销售额')
plt.tight_layout()
plt.show()
# 相关性分析
correlation_matrix = sales_data[['销售额', '订单数']].corr()
print("\n相关性矩阵:")
print(correlation_matrix)
案例2:用户行为分析
# 用户行为分析
# 创建模拟用户数据
np.random.seed(123)
user_data = pd.DataFrame({
'用户ID': range(1, 101),
'年龄': np.random.randint(18, 60, 100),
'性别': np.random.choice(['男', '女'], 100),
'注册天数': np.random.randint(1, 1000, 100),
'活跃天数': np.random.randint(1, 500, 100),
'消费金额': np.random.exponential(1000, 100),
'点击次数': np.random.poisson(50, 100)
})
# 计算用户价值
user_data['日均活跃'] = user_data['活跃天数'] / user_data['注册天数']
user_data['用户价值'] = (user_data['消费金额'] / user_data['注册天数']) * 100
# RFM分析
def calculate_rfm_score(data):
"""计算RFM得分"""
# Recency:最近活跃(这里用注册天数代替)
# Frequency:活跃频率(日均活跃)
# Monetary:消费金额
data['R_score'] = pd.qcut(data['注册天数'], 4, labels=[4, 3, 2, 1])
data['F_score'] = pd.qcut(data['日均活跃'], 4, labels=[1, 2, 3, 4])
data['M_score'] = pd.qcut(data['消费金额'], 4, labels=[1, 2, 3, 4])
return data
user_data = calculate_rfm_score(user_data)
user_data['RFM总分'] = user_data['R_score'].astype(int) + user_data['F_score'].astype(int) + user_data['M_score'].astype(int)
# 用户分群
def segment_users(rfm_score):
if rfm_score >= 10:
return '高价值用户'
elif rfm_score >= 7:
return '中价值用户'
else:
return '低价值用户'
user_data['用户分群'] = user_data['RFM总分'].apply(segment_users)
# 可视化分析
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
# 1. 用户年龄分布
axes[0, 0].hist(user_data['年龄'], bins=15, alpha=0.7, color='lightcoral', edgecolor='black')
axes[0, 0].set_title('用户年龄分布')
axes[0, 0].set_xlabel('年龄')
axes[0, 0].set_ylabel('用户数')
# 2. 性别分布
gender_counts = user_data['性别'].value_counts()
axes[0, 1].pie(gender_counts.values, labels=gender_counts.index, autopct='%1.1f%%', colors=['lightblue', 'lightpink'])
axes[0, 1].set_title('用户性别分布')
# 3. 用户价值分布
segment_counts = user_data['用户分群'].value_counts()
axes[0, 2].bar(segment_counts.index, segment_counts.values, color=['gold', 'orange', 'red'])
axes[0, 2].set_title('用户价值分群')
axes[0, 2].set_xlabel('用户分群')
axes[0, 2].set_ylabel('用户数')
# 4. 年龄与消费关系
axes[1, 0].scatter(user_data['年龄'], user_data['消费金额'], alpha=0.6)
axes[1, 0].set_title('年龄与消费关系')
axes[1, 0].set_xlabel('年龄')
axes[1, 0].set_ylabel('消费金额')
# 5. RFM分布
rfm_scores = user_data['RFM总分'].value_counts().sort_index()
axes[1, 1].plot(rfm_scores.index, rfm_scores.values, marker='o')
axes[1, 1].set_title('RFM总分分布')
axes[1, 1].set_xlabel('RFM总分')
axes[1, 1].set_ylabel('用户数')
axes[1, 1].grid(True, alpha=0.3)
# 6. 热力图:各分群特征
pivot_table = user_data.pivot_table(index='用户分群', values=['年龄', '注册天数', '消费金额'], aggfunc='mean')
sns.heatmap(pivot_table, annot=True, fmt='.1f', cmap='YlOrRd', ax=axes[1, 2])
axes[1, 2].set_title('各用户分群特征对比')
plt.tight_layout()
plt.show()
print("\n用户分群统计:")
print(user_data['用户分群'].value_counts())
print("\n各分群平均消费:")
print(user_data.groupby('用户分群')['消费金额'].mean())
常用技巧
1. 数据清洗技巧
# 处理缺失值
def handle_missing_values(df):
# 检查缺失值
missing = df.isnull().sum()
print("缺失值统计:")
print(missing[missing > 0])
# 填充策略
# 数值型:用均值填充
numeric_cols = df.select_dtypes(include=[np.number]).columns
df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].mean())
# 分类型:用众数填充
categorical_cols = df.select_dtypes(include=['object']).columns
for col in categorical_cols:
df[col] = df[col].fillna(df[col].mode()[0])
return df
# 异常值处理
def remove_outliers(df, column):
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
return df[(df[column] >= lower_bound) & (df[column] <= upper_bound)]
2. 数据分析模板
class DataAnalyzer:
def __init__(self, data_path):
self.data = pd.read_csv(data_path)
def quick_analysis(self):
"""快速分析报告"""
print("="*50)
print("数据快速分析报告")
print("="*50)
print(f"数据形状: {self.data.shape}")
print(f"\n数据类型:")
print(self.data.dtypes)
print(f"\n缺失值统计:")
print(self.data.isnull().sum())
print(f"\n描述性统计:")
print(self.data.describe())
print(f"\n前5行数据:")
print(self.data.head())
def visualize_distributions(self, columns=None):
"""可视化数值分布"""
if columns is None:
columns = self.data.select_dtypes(include=[np.number]).columns
fig, axes = plt.subplots(len(columns), 2, figsize=(12, 4*len(columns)))
for i, col in enumerate(columns):
# 直方图
axes[i, 0].hist(self.data[col].dropna(), bins=30, alpha=0.7, color='skyblue', edgecolor='black')
axes[i, 0].set_title(f'{col}分布直方图')
axes[i, 0].set_xlabel(col)
axes[i, 0].set_ylabel('频数')
# 箱线图
axes[i, 1].boxplot(self.data[col].dropna())
axes[i, 1].set_title(f'{col}箱线图')
axes[i, 1].set_ylabel(col)
plt.tight_layout()
plt.show()
def correlation_analysis(self):
"""相关性分析"""
numeric_data = self.data.select_dtypes(include=[np.number])
correlation = numeric_data.corr()
plt.figure(figsize=(10, 8))
sns.heatmap(correlation, annot=True, cmap='coolwarm', center=0, fmt='.2f')
plt.title('变量相关性热力图')
plt.show()
return correlation
3. 性能优化技巧
# 使用向量化操作替代循环
# 慢的方法
result = []
for value in data:
result.append(value * 2)
# 快的方法(向量化)
result = data * 2
# 使用pandas内置函数
# 慢的方法
df['new_col'] = df['col'].apply(lambda x: process(x))
# 快的方法(如果可能)
df['new_col'] = process(df['col'])
# 使用合适的数据类型
# 将分类数据转换为category类型
df['category_column'] = df['category_column'].astype('category')
学习资源
在线资源
-
官方文档
- Pandas: https://pandas.pydata.org/docs/
- NumPy: https://numpy.org/doc/
- Matplotlib: https://matplotlib.org/stable/contents.html
-
学习平台
- DataCamp: https://www.datacamp.com/
- Kaggle: https://www.kaggle.com/learn
- 廖雪峰Python教程: https://www.liaoxuefeng.com/
-
数据集资源
- UCI Machine Learning Repository
- Kaggle Datasets
- 国家统计局公开数据
推荐书籍
- 《利用Python进行数据分析》(Wes McKinney)
- 《Python数据科学手册》(Jake VanderPlas)
- 《统计学习方法》(李航)
最佳实践
- 始终从理解业务问题开始
- 数据清洗占80%的工作时间
- 可视化是理解数据的关键
- 记录每一步分析过程
- 保持代码可重复性