Pandas数据分析知识点总结
·
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() |
学习建议
- 先掌握基础:熟悉Series和DataFrame的创建和基本属性
- 重点练习索引:loc和iloc是最常用的操作
- 多做实战:找一些CSV数据练习读取、清洗、分析的完整流程
- 循序渐进:从简单查询→数据运算→分组聚合→复杂合并逐步进阶
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)