Pandas数据分析知识点总结

一、Pandas框架概述

1、Pandas介绍

  • Pandas是什么:Python的第三方包,专门用于处理结构化数据(类似Excel表格的数据),主要功能包括数据清洗、处理和分析。
  • 为什么用Pandas
    • 速度快:底层基于NumPy构建,比纯Python循环快很多
    • 处理缺失数据:有专门的API处理空值
    • 强大的分组聚合:轻松实现数据统计分析
  • 适用场景
    • 单机小数据集处理(Excel卡顿但数据量不大时)
    • 大数据ETL流程中的数据清洗环节

2、安装方式

# 使用pip安装,指定清华镜像源下载更快
pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple/

提示:如果安装了Anaconda,Pandas已经默认安装好了,无需额外安装。

3、快速入门

基础语法讲解

import pandas as pd  # 导入pandas库,约定俗成简称为pd

# 读取CSV文件,返回DataFrame对象(表格数据)
df = pd.read_csv('data.csv', encoding='gbk')  # encoding='gbk'支持中文

示例说明
假设data.csv内容如下:

姓名,年龄,城市
小明,25,北京
小红,28,上海

执行代码后,df变量就包含了表格数据,可以像操作Excel一样处理它:

print(df)  # 打印整个表格
print(df['姓名'])  # 只查看"姓名"列

二、数据结构与数据类型

1、核心数据结构

Series:一维数组对象(类似带标签的列表)

# 创建Series
s = pd.Series([10, 20, 30], index=['A', 'B', 'C'])
print(s)
# 输出:
# A    10
# B    20
# C    30
# dtype: int64

基础Python等价写法

# 用字典实现类似功能
s_dict = {'A': 10, 'B': 20, 'C': 30}
print(s_dict['A'])  # 输出:10

DataFrame:二维表格对象(类似Excel表格)

# 创建DataFrame
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [25, 28, 22],
    '城市': ['北京', '上海', '广州']
}
df = pd.DataFrame(data)
print(df)
# 输出:
#    姓名  年龄  城市
# 0  小明  25  北京
# 1  小红  28  上海
# 2  小刚  22  广州

基础Python等价写法

# 用列表+字典实现类似功能
data_list = [
    {'姓名': '小明', '年龄': 25, '城市': '北京'},
    {'姓名': '小红', '年龄': 28, '城市': '上海'},
    {'姓名': '小刚', '年龄': 22, '城市': '广州'}
]

2、常用属性

属性 说明 示例
shape 数据形状(行数, 列数) df.shape(3, 3)
index 行索引列表 df.index[0, 1, 2]
columns 列索引列表 df.columns['姓名', '年龄', '城市']
values 数据值(数组形式) df.values → 二维数组
dtypes 各列数据类型 df.dtypes
T 转置(行变列,列变行) df.T

示例

print(df.shape)      # 输出:(3, 3) 表示3行3列
print(df.columns)    # 输出:Index(['姓名', '年龄', '城市'], dtype='object')
print(df.dtypes)     # 查看每列的数据类型

3、数据类型

类型 说明 示例
object 字符串类型 ‘小明’, ‘北京’
int 整数类型 1, 25, 100
float 浮点数类型 3.14, 25.5
datetime 日期时间类型 2024-01-01
timedelta 时间差类型 5天, 3小时
category 分类类型 性别(男/女), 颜色(红/绿/蓝)
bool 布尔类型 True, False
nan 空值类型 缺失的数据

示例

import pandas as pd

# 创建不同类型的数据
df = pd.DataFrame({
    '姓名': ['小明', '小红'],           # object类型
    '年龄': [25, 28],                  # int类型
    '身高': [1.75, 1.68],             # float类型
    '是否学生': [True, False],         # bool类型
    '生日': pd.to_datetime(['2000-01-01', '1998-05-15'])  # datetime类型
})
print(df.dtypes)

三、基本数据操作

1、索引操作

三种索引方式对比

方式 语法 说明
直接索引 df['列名']['行标签'] 先选列再选行
loc df.loc['行标签', '列标签'] 按标签索引
iloc df.iloc[行下标, 列下标] 按下标索引(从0开始)

示例

# 准备数据
data = {'open': [23.53, 22.80, 22.88], 'close': [24.16, 23.53, 22.82]}
df = pd.DataFrame(data, index=['2018-02-27', '2018-02-26', '2018-02-23'])

# 直接索引:先列后行
print(df['open']['2018-02-27'])   # 输出:23.53

# loc:先行后列,用标签
print(df.loc['2018-02-27', 'open'])  # 输出:23.53

# iloc:先行后列,用数字下标
print(df.iloc[0, 0])  # 第一行第一列,输出:23.53
print(df.iloc[:3, :2])  # 前3行前2列

2、赋值操作

# 方式1:直接赋值(推荐)
df['close'] = 1  # 将close列所有值设为1

# 方式2:点语法(列名无空格时可用)
df.close = 1  # 和上面效果相同

注意:如果列名包含空格,只能用方括号方式:

df['new column'] = 10  # 正确
# df.new column = 10   # 错误,会报错

3、排序操作

# 按值排序
df_sorted = df.sort_values(by='open', ascending=True)  # ascending=True升序

# 按索引排序
df_sorted = df.sort_index()  # 默认按索引升序排列

示例

data = {'name': ['B', 'A', 'C'], 'value': [30, 10, 20]}
df = pd.DataFrame(data)

print(df.sort_values(by='value'))  # 按value列升序
print(df.sort_index(ascending=False))  # 按索引降序

四、DataFrame运算

1、算术运算

# 对整列进行运算
df['open'].add(1)    # 所有开盘价+1
df['open'].sub(1)    # 所有开盘价-1
df['open'].mul(2)    # 所有开盘价×2
df['open'].div(2)    # 所有开盘价÷2

基础Python等价写法

# 用for循环实现
open_values = [23.53, 22.80, 22.88]
result = [x + 1 for x in open_values]  # [24.53, 23.80, 23.88]

2、逻辑运算

# 筛选open > 23的数据
df[df['open'] > 23]

# 多条件筛选(注意用&连接,每个条件加括号)
df[(df['open'] > 23) & (df['open'] < 24)]

# 使用query方法(更简洁)
df.query("open < 24 & open > 23")

# 判断是否在列表中
df[df['open'].isin([23.53, 23.85])]

示例

data = {'price': [23.5, 22.8, 24.1, 21.9], 'volume': [100, 200, 150, 300]}
df = pd.DataFrame(data)

# 筛选价格在22到24之间的行
result = df[(df['price'] > 22) & (df['price'] < 24)]
print(result)

3、统计运算

df.describe()      # 综合统计(count, mean, std, min, max等)
df.max(0)          # 每列最大值(axis=0表示按列)
df.min(0)          # 每列最小值
df.mean(0)         # 每列平均值
df.std(0)          # 每列标准差
df.idxmax(0)       # 最大值所在的行索引
df.idxmin(0)       # 最小值所在的行索引

示例

data = {'score': [85, 92, 78, 90, 88]}
df = pd.DataFrame(data)

print(df.describe())
# 输出包含:count(数量), mean(均值), std(标准差), min(最小值), 25%/50%/75%(分位数), max(最大值)

4、累计统计

df['p_change'].cumsum()   # 累计求和(前1个、前2个、...、前n个数的和)
df['p_change'].cummax()   # 累计最大值
df['p_change'].cummin()   # 累计最小值
df['p_change'].cumprod()  # 累计乘积

示例

data = {'value': [1, 2, 3, 4, 5]}
df = pd.DataFrame(data)

print(df['value'].cumsum())
# 输出:
# 0     1
# 1     3  (1+2)
# 2     6  (1+2+3)
# 3    10  (1+2+3+4)
# 4    15  (1+2+3+4+5)

5、自定义运算

# 对指定列应用自定义函数
df[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)

解释

  • apply():对每行或每列应用函数
  • lambda x: ...:匿名函数,x代表当前行或列
  • axis=0:按列计算;axis=1:按行计算

示例

data = {'a': [1, 2, 3], 'b': [4, 5, 6]}
df = pd.DataFrame(data)

# 计算每列的最大值减最小值
result = df.apply(lambda x: x.max() - x.min(), axis=0)
print(result)  # 输出:a    2, b    2

# 计算每行的和
row_sum = df.apply(lambda x: x.sum(), axis=1)
print(row_sum)  # 输出:0    5, 1    7, 2    9

五、文件读取与存储

1、CSV文件

# 读取CSV文件
df = pd.read_csv('file.csv', usecols=['open', 'close'])  # 只读取指定列

# 保存到CSV文件
df.to_csv('output.csv', columns=['open'], index=False)  # index=False不保存行索引

示例

# 假设有data.csv文件:
# date,open,close
# 2024-01-01,23.5,24.1
# 2024-01-02,24.0,24.5

df = pd.read_csv('data.csv')
print(df)

# 保存只包含close列的数据
df.to_csv('close_only.csv', columns=['close'], index=False)

2、JSON文件

# 读取JSON文件
df = pd.read_json('file.json', orient='records', lines=True)

# 保存为JSON文件
df.to_json('output.json', orient='records', lines=True)

示例

# JSON文件格式(每行一个JSON对象):
# {"name": "小明", "age": 25}
# {"name": "小红", "age": 28}

df = pd.read_json('data.json', orient='records', lines=True)
print(df)

3、MySQL数据库

from sqlalchemy import create_engine

# 创建数据库连接引擎
engine = create_engine('mysql+pymysql://user:pass@host:port/db_name')

# 从数据库读取数据
df = pd.read_sql('table_name', engine)

# 将数据写入数据库
df.to_sql('table_name', engine, index=False, if_exists='append')

参数说明

  • user: 数据库用户名
  • pass: 数据库密码
  • host: 数据库地址(本地为127.0.0.1)
  • port: 端口(MySQL默认3306)
  • db_name: 数据库名称
  • if_exists: 'append’追加数据,'replace’替换表,'fail’如果表存在报错

六、数据增删改查

1、增加列

# 方式1:直接赋值(所有行相同值)
df['new_col'] = 33

# 方式2:赋值列表(每个行对应一个值)
df['new_col'] = [1, 2, 3, 4, 5]

# 方式3:使用assign方法(不修改原df,返回新df)
df_new = df.assign(new_col=[1, 2, 3, 4, 5])

示例

data = {'name': ['小明', '小红', '小刚'], 'age': [25, 28, 22]}
df = pd.DataFrame(data)

# 添加新列
df['city'] = ['北京', '上海', '广州']
df['score'] = df['age'] * 4  # 根据已有列计算
print(df)

2、删除操作

df.drop([0, 2])           # 删除索引为0和2的行(默认axis=0)
df.drop(['col'], axis=1)  # 删除名为col的列(axis=1表示列)
del df['col']             # 直接删除列(永久修改原df)
df.drop_duplicates()      # 删除重复行

注意drop()默认不修改原数据,需重新赋值或加inplace=True

df = df.drop([0, 2])           # 方式1:重新赋值
df.drop([0, 2], inplace=True)  # 方式2:直接修改原df

3、修改数据

# 修改整列
df['GDP'] = [5, 4, 3, 2, 1]

# 替换特定值
df.replace(1960, 19600)  # 将所有1960替换为19600

示例

data = {'country': ['中国', '美国', '日本'], 'year': [1960, 1970, 1960]}
df = pd.DataFrame(data)

# 将年份1960替换为2000
df.replace(1960, 2000, inplace=True)
print(df)

4、查询数据

df.head(10)              # 查看前10行(默认前5行)
df.tail(5)               # 查看后5行
df[['country', 'GDP']]   # 查看指定列
df[0:3]                  # 切片查看行(第0-2行)
df.query('country=="中国"')  # 使用查询语句

示例

data = {'country': ['中国', '美国', '日本', '中国'], 'GDP': [10, 20, 5, 15]}
df = pd.DataFrame(data)

# 查询中国的数据
china_data = df.query('country=="中国"')
print(china_data)

# 查询GDP大于10的行
high_gdp = df[df['GDP'] > 10]
print(high_gdp)

七、缺失值处理

1、判断缺失值

pd.isnull(df)    # 每个单元格判断是否为空
pd.notnull(df)   # 每个单元格判断是否不为空
df.isnull().sum()  # 统计每列空值数量

示例

data = {'name': ['小明', None, '小刚'], 'age': [25, 28, None]}
df = pd.DataFrame(data)

print(df.isnull())       # 显示True/False矩阵
print(df.isnull().sum()) # 统计每列空值数:name:1, age:1

2、处理方式

# 删除包含缺失值的行
df_clean = df.dropna()

# 用均值填充缺失值
df['col'].fillna(df['col'].mean(), inplace=True)

# 将特定标记替换为NaN
df.replace('?', np.nan, inplace=True)

示例

import numpy as np

data = {'score': [85, None, 78, 90, None]}
df = pd.DataFrame(data)

# 方式1:删除缺失值
df_drop = df.dropna()

# 方式2:用均值填充
df_fill = df.copy()
df_fill['score'].fillna(df_fill['score'].mean(), inplace=True)
print(df_fill)

八、数据合并

1、pd.concat(拼接)

pd.concat([df1, df2], axis=0)   # 纵向拼接(增加行)
pd.concat([df1, df2], axis=1)   # 横向拼接(增加列)

示例

df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})

# 纵向拼接(上下合并)
result = pd.concat([df1, df2], axis=0, ignore_index=True)
print(result)

# 横向拼接(左右合并)
df3 = pd.DataFrame({'C': [9, 10], 'D': [11, 12]})
result = pd.concat([df1, df3], axis=1)
print(result)

2、pd.merge(连接)

pd.merge(left, right, how='inner', on='key')  # 内连接
pd.merge(left, right, how='left', on='key')   # 左连接
pd.merge(left, right, how='right', on='key')  # 右连接
pd.merge(left, right, how='outer', on='key')  # 外连接

连接方式说明

方式 说明
inner 只保留两表都有的行(交集)
left 保留左表所有行,右表匹配不到的用NaN
right 保留右表所有行,左表匹配不到的用NaN
outer 保留两表所有行(并集)

示例

left = pd.DataFrame({'key': ['K0', 'K1'], 'A': ['A0', 'A1']})
right = pd.DataFrame({'key': ['K1', 'K2'], 'B': ['B1', 'B2']})

# 内连接(只保留key=K1的行)
result = pd.merge(left, right, how='inner', on='key')
print(result)

# 左连接(保留left所有行)
result = pd.merge(left, right, how='left', on='key')
print(result)

九、数据分组

1、分组操作

# 按一列分组
grouped = df.groupby('gender_group')

# 按多列分组
grouped = df.groupby(['gender_group', 'city'])

# 获取指定分组
grouped.get_group('Female')

示例

data = {'gender': ['男', '女', '男', '女'], 'score': [85, 90, 88, 92]}
df = pd.DataFrame(data)

# 按性别分组
grouped = df.groupby('gender')

# 获取男生组
male_group = grouped.get_group('男')
print(male_group)

2、分组聚合

# 单列聚合
df.groupby('city').customer.sum()

# 多列不同聚合
df.groupby(['city', 'channel']).agg({'revenue':'mean', 'unit_cost':'sum'})

示例

data = {'city': ['北京', '上海', '北京', '上海'], 
        'product': ['A', 'A', 'B', 'B'],
        'sales': [100, 150, 80, 120]}
df = pd.DataFrame(data)

# 按城市分组,计算销售总和
city_sales = df.groupby('city')['sales'].sum()
print(city_sales)

# 按城市和产品分组,计算均值
result = df.groupby(['city', 'product']).agg({'sales': 'mean'})
print(result)

3、分组过滤

# 筛选满足条件的分组
df.groupby('city').filter(lambda s: s['revenue'].mean() > 200)

解释

  • 先按city分组
  • 对每个分组应用lambda函数
  • 只有满足条件(均值>200)的分组才会被保留

十、交叉表与透视表

1、交叉表

# 统计两列的组合频率
pd.crosstab(df['性别'], df['购买'])

示例

data = {
    '性别': ['男', '女', '男', '女', '男', '女'],
    '购买': ['是', '否', '是', '是', '否', '否']
}
df = pd.DataFrame(data)

# 创建交叉表
result = pd.crosstab(df['性别'], df['购买'])
print(result)
# 输出:
# 购买  否  是
# 性别        
# 女    2   1
# 男    1   2

2、透视表

# 创建透视表
data.pivot_table(values='金额', index='性别', columns='购买', aggfunc='mean')

示例

data = {
    '性别': ['男', '女', '男', '女', '男', '女'],
    '购买': ['是', '否', '是', '是', '否', '否'],
    '金额': [100, 150, 200, 130, 160, 120]
}
df = pd.DataFrame(data)

# 创建透视表,计算不同性别购买与否的平均金额
result = df.pivot_table(values='金额', index='性别', columns='购买', aggfunc='mean')
print(result)

核心知识点总结

模块 核心内容 重点方法
数据结构 Series(一维)、DataFrame(二维) pd.Series(), pd.DataFrame()
索引操作 直接索引、loc(标签)、iloc(下标) df.loc[], df.iloc[]
统计分析 describe、聚合函数、累计函数 df.describe(), df.mean(), df.cumsum()
文件IO CSV、JSON、MySQL pd.read_csv(), pd.read_json()
数据处理 缺失值、合并、分组、透视表 df.dropna(), pd.merge(), df.groupby()

学习建议

  1. 先掌握基础:熟悉Series和DataFrame的创建和基本属性
  2. 重点练习索引:loc和iloc是最常用的操作
  3. 多做实战:找一些CSV数据练习读取、清洗、分析的完整流程
  4. 循序渐进:从简单查询→数据运算→分组聚合→复杂合并逐步进阶
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐