跳到主要内容

Pandas 基础

Pandas 是 Python 数据分析的核心库,提供了高效的数据结构 DataFrame 和 Series,能够方便地处理表格数据。本章将详细介绍 Pandas 的核心概念和使用方法。

根据 Pandas 官方文档,Pandas 提供两种主要的数据结构:

  • Series:一维标签数组
  • DataFrame:二维表格数据结构

为什么使用 Pandas?

对比 Python 列表和字典

# 使用 Python 字典存储表格数据
data = [
{'name': '张三', 'age': 25, 'city': '北京'},
{'name': '李四', 'age': 30, 'city': '上海'},
{'name': '王五', 'age': 35, 'city': '广州'}
]

# 访问数据需要遍历
for person in data:
if person['age'] > 28:
print(person['name'], person['age'])

# 使用 Pandas
import pandas as pd

df = pd.DataFrame({
'name': ['张三', '李四', '王五'],
'age': [25, 30, 35],
'city': ['北京', '上海', '广州']
})

# 一行代码完成筛选
print(df[df['age'] > 28]['name'])

Pandas 的优势:

  • 简洁:数据操作代码更短
  • 高效:底层使用 NumPy 优化
  • 功能强大:内置丰富的统计分析功能
  • 灵活:支持多种数据格式

Series

Series 是带标签的一维数组,类似于 Python 字典或 NumPy 数组。

创建 Series

import pandas as pd
import numpy as np

# 从列表创建
s = pd.Series([1, 2, 3, 4, 5])
print(s)
# 输出:
# 0 1
# 1 2
# 2 3
# 3 4
# 4 5
# dtype: int64

# 指定索引
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
print(s)
# 输出:
# a 1
# b 2
# c 3
# d 4
# e 5
# dtype: int64

# 从字典创建
s = pd.Series({'a': 1, 'b': 2, 'c': 3})
print(s)
# 输出:
# a 1
# b 2
# c 3
# dtype: int64

Series 属性

s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])

print(s.values) # 值数组: [10 20 30 40]
print(s.index) # 索引: Index(['a', 'b', 'c', 'd'], dtype='object')
print(s.dtype) # 数据类型: int64
print(s.shape) # 形状: (4,)
print(s.size) # 元素数量: 4

访问 Series 元素

s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])

# 使用索引标签
print(s['a']) # 10
print(s[['a', 'c']]) # a 10, c 30

# 使用位置索引
print(s[0]) # 10
print(s[0:3]) # a 10, b 20, c 30

# 布尔索引
print(s[s > 25]) # c 30, d 40

Series 运算

s = pd.Series([1, 2, 3, 4])

# 算术运算
print(s + 1) # [2 3 4 5]
print(s * 2) # [2 4 6 8]

# 与另一个 Series 运算
s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
s2 = pd.Series([10, 20, 30], index=['a', 'b', 'c'])
print(s1 + s2) # a 11, b 22, c 33

DataFrame

DataFrame 是 Pandas 最核心的数据结构,类似于 Excel 表格或 SQL 表。

创建 DataFrame

import pandas as pd

# 从字典创建(最常用)
df = pd.DataFrame({
'name': ['张三', '李四', '王五', '赵六'],
'age': [25, 30, 35, 28],
'city': ['北京', '上海', '广州', '深圳'],
'salary': [10000, 15000, 20000, 12000]
})
print(df)
# 输出:
# name age city salary
# 0 张三 25 北京 10000
# 1 李四 30 上海 15000
# 2 王五 35 广州 20000
# 3 赵六 28 深圳 12000

# 从列表字典创建
data = [
{'name': '张三', 'age': 25},
{'name': '李四', 'age': 30},
{'name': '王五', 'age': 35}
]
df = pd.DataFrame(data)

# 指定索引
df = pd.DataFrame({
'name': ['张三', '李四', '王五'],
'age': [25, 30, 35]
}, index=['a', 'b', 'c'])

# 从二维数组创建
arr = np.array([[1, 2, 3], [4, 5, 6]])
df = pd.DataFrame(arr, columns=['A', 'B', 'C'])

DataFrame 基本操作

# 创建示例数据
df = pd.DataFrame({
'name': ['张三', '李四', '王五', '赵六'],
'age': [25, 30, 35, 28],
'city': ['北京', '上海', '广州', '深圳'],
'salary': [10000, 15000, 20000, 12000]
})

# 查看数据
print(df.head()) # 前5行
print(df.tail()) # 后5行

# 查看基本信息
print(df.shape) # (4, 4) - 4行4列
print(df.columns) # 列名
print(df.dtypes) # 每列的数据类型
print(df.index) # 行索引

# 查看统计信息
print(df.describe()) # 数值列的统计摘要

# 查看数据具体内容
print(df.info()) # 数据类型和缺失值信息

选择列

df = pd.DataFrame({
'name': ['张三', '李四', '王五'],
'age': [25, 30, 35],
'salary': [10000, 15000, 20000]
})

# 选择单列 - 返回 Series
print(df['name'])
# 0 张三
# 1 李四
# 2 王五
# Name: name, dtype: object

# 选择多列 - 返回 DataFrame
print(df[['name', 'salary']])
# name salary
# 0 张三 10000
# 1 李四 15000
# 2 王五 20000

选择行

df = pd.DataFrame({
'name': ['张三', '李四', '王五', '赵六'],
'age': [25, 30, 35, 28],
'city': ['北京', '上海', '广州', '深圳']
})

# 使用 loc - 通过标签选择
print(df.loc[0]) # 选择第一行
print(df.loc[0:2]) # 选择第1-3行
print(df.loc[df['age'] > 28]) # 条件筛选

# 使用 iloc - 通过位置选择
print(df.iloc[0]) # 选择第一行
print(df.iloc[0:2]) # 选择前两行
print(df.iloc[:, 0]) # 选择第一列
print(df.iloc[0:2, 1:3]) # 行列切片

添加和删除列

df = pd.DataFrame({
'name': ['张三', '李四', '王五'],
'age': [25, 30, 35]
})

# 添加新列
df['city'] = ['北京', '上海', '广州']
df['salary'] = [10000, 15000, 20000]

# 计算新列
df['bonus'] = df['salary'] * 0.1

# 删除列
df = df.drop('bonus', axis=1)
# 或者
del df['bonus']

print(df)

添加和删除行

df = pd.DataFrame({
'name': ['张三', '李四', '王五'],
'age': [25, 30, 35]
}, index=[0, 1, 2])

# 添加行
new_row = pd.Series({'name': '赵六', 'age': 28})
df = pd.concat([df, new_row.to_frame().T], ignore_index=True)

# 删除行
df = df.drop(0) # 删除索引为0的行

print(df)

数据操作

排序

df = pd.DataFrame({
'name': ['张三', '李四', '王五', '赵六'],
'age': [25, 30, 35, 28],
'salary': [10000, 15000, 20000, 12000]
})

# 按列排序
df_sorted = df.sort_values('age') # 升序
df_sorted = df.sort_values('age', ascending=False) # 降序

# 多列排序
df_sorted = df.sort_values(['age', 'salary'], ascending=[True, False])

# 按索引排序
df_sorted = df.sort_index()

print(df_sorted)

统计计算

df = pd.DataFrame({
'A': [1, 2, 3, 4, 5],
'B': [10, 20, 30, 40, 50],
'C': [100, 200, 300, 400, 500]
})

# 基本统计
print(df.sum()) # 每列求和
print(df.mean()) # 每列平均值
print(df.median()) # 每列中位数
print(df.std()) # 每列标准差
print(df.min()) # 每列最小值
print(df.max()) # 每列最大值

# 统计函数
print(df.count()) # 非空值数量
print(df.quantile(0.5)) # 50%分位数

# 累计统计
print(df.cumsum()) # 累计求和
print(df.cummax()) # 累计最大值

字符串操作

df = pd.DataFrame({
'name': ['zhang san', 'li si', 'wang wu'],
'city': ['beijing', 'shanghai', 'guangzhou']
})

# 转换为大写
df['name'] = df['name'].str.title() # 'Zhang San'
df['city'] = df['city'].str.upper() # 'BEIJING'

# 字符串替换
df['city'] = df['city'].str.replace('beijing', '北京')

# 字符串分割
df['name'].str.split(' ')

# 字符串包含判断
df[df['name'].str.contains('Zhang')]

处理缺失值

df = pd.DataFrame({
'A': [1, 2, np.nan, 4, 5],
'B': [10, np.nan, 30, np.nan, 50],
'C': [100, 200, 300, 400, 500]
})

# 检测缺失值
print(df.isnull()) # 返回布尔DataFrame
print(df.isnull().sum()) # 每列缺失值数量

# 删除缺失值
df_cleaned = df.dropna() # 删除有缺失值的行
df_cleaned = df.dropna(axis=1) # 删除有缺失值的列

# 填充缺失值
df_filled = df.fillna(0) # 用0填充
df_filled = df.fillna(df.mean()) # 用均值填充
df_filled = df.fillna(method='ffill') # 用前一个值填充
df_filled = df.fillna(method='bfill') # 用后一个值填充

数据类型转换

# 创建包含混合类型的列
df = pd.DataFrame({
'A': ['1', '2', '3'],
'B': ['1.5', '2.5', '3.5'],
'C': ['2024-01-01', '2024-01-02', '2024-01-03']
})

# 转换为数值类型
df['A'] = df['A'].astype(int)
df['B'] = df['B'].astype(float)

# 转换为日期类型
df['C'] = pd.to_datetime(df['C'])

# 查看数据类型
print(df.dtypes)

实战示例

示例:学生成绩分析

# 创建学生成绩数据
df = pd.DataFrame({
'name': ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十'],
'chinese': [85, 90, 78, 92, 88, 76, 95, 82],
'math': [90, 85, 82, 95, 78, 88, 92, 80],
'english': [88, 92, 80, 85, 90, 82, 78, 95]
})

# 计算总分
df['total'] = df['chinese'] + df['math'] + df['english']

# 计算平均分
df['average'] = df['total'] / 3

# 按总分排序
df_sorted = df.sort_values('total', ascending=False)

# 找出各科最高分
print('语文最高分:', df['chinese'].max())
print('数学最高分:', df['math'].max())
print('英语最高分:', df['english'].max())

# 找出总分前三名
top3 = df_sorted.head(3)
print('总分前三名:')
print(top3[['name', 'total']])

# 统计各科平均分
print('各科平均分:')
print(df[['chinese', 'math', 'english']].mean())

示例:电商订单分析

# 模拟电商订单数据
df = pd.DataFrame({
'order_id': ['A001', 'A002', 'A003', 'A004', 'A005'],
'customer': ['张三', '李四', '王五', '张三', '李四'],
'product': ['手机', '电脑', '平板', '耳机', '手机'],
'quantity': [1, 1, 2, 3, 2],
'price': [5000, 8000, 3000, 200, 5000]
})

# 计算每笔订单总金额
df['total'] = df['quantity'] * df['price']

# 统计每个客户的消费总额
customer_sales = df.groupby('customer')['total'].sum()
print('客户消费总额:')
print(customer_sales)

# 统计每种产品的销售数量
product_sales = df.groupby('product')['quantity'].sum()
print('产品销售数量:')
print(product_sales)

# 统计消费最高的客户
top_customer = customer_sales.idxmax()
top_amount = customer_sales.max()
print(f'消费最高客户: {top_customer}, 金额: {top_amount}')

小结

本章我们学习了:

  1. Pandas 的优势:简洁、高效、功能强大
  2. Series:一维标签数组的创建和操作
  3. DataFrame:二维表格数据的创建和操作
  4. 数据选择:选择列、选择行、布尔索引
  5. 数据操作:排序、统计计算、字符串操作
  6. 缺失值处理:检测、删除、填充
  7. 数据类型转换:数值、日期类型转换
  8. 实战示例:学生成绩分析、电商订单分析

练习

  1. 创建一个包含 10 名学生信息的 DataFrame(姓名、年龄、分数)
  2. 计算每个学生的总分和平均分
  3. 找出分数最高和最低的学生
  4. 按分数降序排列
  5. 统计每个分数段的学生人数

参考资源

下一步

现在你已经掌握了 Pandas 的基础,接下来让我们学习 数据读取与写入,了解如何从各种文件格式导入和导出数据!