pandas使用笔记、数据清洗、json_normalize

文章目录

Pandas 是 Python 中用于数据分析和数据处理的"瑞士军刀",是目前数据科学领域最核心的工具库之一。必须掌握。

构建数据

构建数据主要通过DataFrame来实现。

构建数据-列向导
python 复制代码
import pandas as pd

data = {
    '姓名': ['张三', '李四', '王五'],
    '年龄': [25, 30, 35],
    '城市': ['北京', '上海', '广州']
}

df = pd.DataFrame(data)
print(df)

输出结果:

python 复制代码
   姓名  年龄  城市
0  张三  25  北京
1  李四  30  上海
2  王五  35  广州

这么理解就好理解了:

姓名是列名,张三等是列下面的数据,每一列的行数要相等。

构建数据-行向导

因为行数据本身没有列名,所以构建时需要显示指定列名(columns)。

python 复制代码
import pandas as pd

# 每一组中括号代表一行数据
data = [
    ['张三', 25, '北京'],
    ['李四', 30, '上海'],
    ['王五', 35, '广州']
]

# 必须显式指定列名
df = pd.DataFrame(data, columns=['姓名', '年龄', '城市'])
print(df)

输出结果:

python 复制代码
   姓名  年龄  城市
0  张三  25  北京
1  李四  30  上海
2  王五  35  广州
构建数据-矩阵导向
python 复制代码
import pandas as pd
import numpy as np

# 生成一个 3行4列 的随机数矩阵
arr = np.random.randn(3, 4)

df = pd.DataFrame(arr, columns=['A', 'B', 'C', 'D'])
print(df)

输出结果:

python 复制代码
          A         B         C         D
0  0.383721  0.299960 -0.866526 -1.889621
1 -0.418412 -0.084870 -1.008183  0.075037
2 -0.181221  1.113219 -1.296714  1.225547
构建数据-记录导向
python 复制代码
import pandas as pd

data = [
    {'姓名': '张三', '年龄': 25, '城市': '北京'},
    {'姓名': '李四', '年龄': 30, '城市': '上海'},
    # 注意:如果某一行缺少某个字段(比如王五没写城市),Pandas 会自动填 NaN
    {'姓名': '王五', '年龄': 35}
]

df = pd.DataFrame(data)
print(df)

输出结果:

python 复制代码
   姓名  年龄   城市
0  张三  25   北京
1  李四  30   上海
2  王五  35  NaN
构建数据-总结

一句话,纯数据需要指定名,其他都不需要指定列名。

数据 示例
纯数组 ['张三', 25, '北京'] 需要指定列名
列名+数组 '姓名': ['张三', '李四', '王五'] 无需指定列名
键值对 {'姓名': '张三', '年龄': 25, '城市': '北京'} 无需指定列名
读取外部文件
形式 代码示例 说明
CSV 文件 pd.read_csv('data.csv') 最通用的文本格式
Excel 文件 pd.read_excel('data.xlsx') 读取办公文档
Parquet 文件 pd.read_parquet('data.parquet') 大数据/高性能场景首选
SQL 数据库 pd.read_sql(query, conn) 从 MySQL/PostgreSQL 读取

清洗数据示例

清洗数据-1、创建原始数据

新建sales_raw.xlsx文件,内容复制进去:

订单ID 门店名称 销售日期 销售额 客户等级 备注
1001 北京店 2023-01-01 2500 VIP
1002 上海 分店 2023-01-01 3000 vip
1003 广州门店 2023/01/02 1800 Normal 促销订单
1004 深圳店 2023-01-02 2200 NORMAL 重要客户
1001 北京店 2023-01-01 2500 VIP
1005 杭州分店 2023-01-03 High
1006 成都 门店 2023-01-03 2800 normal
1007 武汉店 2023-01-04 3100 新客户
西安分店 2023-01-04 2400 VIP

该数据是有脏数据的。

1、重复数据:订单ID为 1001 的记录重复出现。

2、缺失值:第7行"客户等级"为空,第5行"销售额"为空,第9行"订单ID"为空。

3、格式不一致:

  • 门店名称:有"店"、"分店"、"门店"等多种写法,且包含空格(如"上海 分店")。
  • 客户等级:VIP、vip、High、Normal、normal 大小写和命名不统一。
  • 销售日期:存在 2023-01-01 和 2023/01/02 两种格式。
    4、异常空格:"上海 分店"、"成都 门店"中存在多余空格。
    5、字段冗余:"备注"列存在大量空值,可能无实际用途。
2、使用 Pandas 进行数据清洗

代码:

python 复制代码
import pandas as pd

# 1. 读取原始数据
df = pd.read_excel("sales_raw.xlsx")

print("原始数据形状:", df.shape)
print("前5行数据:")
print(df.head())

# 2. 处理缺失值
# 填充销售额缺失值为该列均值(数值型)
df['销售额'] = df['销售额'].fillna(df['销售额'].mean())

# 填充客户等级缺失值为 'Unknown'(分类变量)
df['客户等级'] = df['客户等级'].fillna('Unknown')

# 删除订单ID为空的整行(关键字段缺失)
df = df.dropna(subset=['订单ID'])

# 3. 去除重复项(基于订单ID)
df = df.drop_duplicates(subset=['订单ID'], keep='first')

# 4. 标准化文本字段
# 清洗门店名称:去除空格、统一后缀为"店"
df['门店名称'] = df['门店名称'].str.replace(' ', '').str.replace('分店|门店', '店', regex=True)

# 统一客户等级:转为大写并映射为标准类别
level_map = {'VIP': 'VIP', 'HIGH': 'High', 'NORMAL': 'Normal', 'UNKNOWN': 'Unknown'}
df['客户等级'] = df['客户等级'].str.upper().map(level_map)

# 5. 统一日期格式
df['销售日期'] = pd.to_datetime(df['销售日期'], errors='coerce')

# 6. 删除冗余列(如无用的备注)
df = df.drop(columns=['备注'], errors='ignore')

# 7. 数据类型优化
df['订单ID'] = df['订单ID'].astype(int)
df['销售额'] = df['销售额'].round(2)

# 8. 查看清洗后结果
print("\n清洗后数据形状:", df.shape)
print("清洗后数据:")
print(df)

# 9. 保存清洗后数据
df.to_excel("sales_cleaned.xlsx", index=False)

部分输出结果:

python 复制代码
清洗后数据形状: (7, 5)
清洗后数据:
   订单ID 门店名称       销售日期     销售额     客户等级
0  1001  北京店 2023-01-01  2500.0      VIP
1  1002  上海店 2023-01-01  3000.0      VIP
2  1003  广州店 2023-01-02  1800.0   Normal
3  1004  深圳店 2023-01-02  2200.0   Normal
5  1005  杭州店 2023-01-03  2537.5     High
6  1006  成都店 2023-01-03  2800.0   Normal
7  1007  武汉店 2023-01-04  3100.0  Unknown

注:销售额 缺失值被填充为均值 2566.67,客户等级 空值标记为 Unknown,所有文本和日期均已标准化。

3、总结下这段代码干了什么

简单来说,刚才那段代码主要干了 4 件"大扫除"的事情,就像整理一个乱糟糟的房间一样:
🗑️ 扔垃圾(处理缺失值)

问题: 表格里有些地方是空的。比如有的行没有"销售额",有的行没有"客户等级"。计算机没法计算空的东西。

怎么修的:

填空缺: 对于"销售额",我们算出其他所有订单的平均数,把空缺填上(或者填0)。对于"客户等级",填上"未知"。

删废行: 如果一行数据连最重要的"订单ID"都没有,那这行数据就彻底废了,直接整行删除。

对应代码: fillna (填充), dropna (删除)
✂️ 剪重复(去除重复项)

问题: "订单1001"在表里出现了两次,内容一模一样。这可能是复制粘贴时手抖多粘了一次。如果不删掉,算总销售额时就会算重。

怎么修的:

告诉电脑:"盯着'订单ID'这一列看,如果发现两个一样的ID,只保留第一个,把后面重复的统统删掉。"

对应代码: drop_duplicates
📏 立规矩(标准化格式)

这是最繁琐的一步,主要是为了统一"写法"。
问题 A(名字乱): 有的叫"上海 分店"(带空格),有的叫"广州门店"(后缀不一样)。

怎么修:

先把所有空格删掉(变成"上海分店")。

再把所有的"分店"、"门店"全部替换成统一的"店"(变成"上海店")。
问题 B(等级乱): 有的是大写"VIP",有的是小写"vip",还有"Normal"。

怎么修:

全部强制转换成大写(VIP, NORMAL)。

建立一个对照表,把它们映射成统一的标准词。

对应代码: .str.replace, .str.upper, .map
🕵️‍♂️ 抓内鬼(修正数据类型)

问题: 在Excel里,"2023-01-01"有时候会被当成普通的文字(字符串),而不是真正的日期。这样你就没法算"这一天距离今天过了多久"。

怎么修的:

强制把"销售日期"这一列刷上一层"时间滤镜",告诉电脑:"别把它当文字,这是时间!"这样以后就能进行时间计算了。

对应代码: pd.to_datetime

读取数据常用方法

类别 文件格式 读取函数 写入函数
文本/表格 CSV / TSV pd.read_csv() df.to_csv()
Excel (.xls, .xlsx) pd.read_excel() df.to_excel()
JSON pd.read_json() df.to_json()
HTML (网页表格) pd.read_html() df.to_html()
高性能/二进制 Parquet pd.read_parquet() df.to_parquet()
HDF5 pd.read_hdf() df.to_hdf()
Pickle (Python专用) pd.read_pickle() df.to_pickle()
Feather pd.read_feather() df.to_feather()
其他/统计 SQL 数据库 pd.read_sql() df.to_sql()
Stata / SAS / SPSS pd.read_stata() df.to_stata()
XML pd.read_xml() df.to_xml()
读取数据 read_json() 读取json字符串

1、创建read_json_from_string.py,代码:

python 复制代码
import pandas as pd

json_data = '''
[
    {"姓名": "张三", "年龄": 25, "城市": "北京"},
    {"姓名": "李四", "年龄": 30, "城市": "上海"},
    {"姓名": "王五", "年龄": 28, "城市": "深圳"}
]
'''

# 2. 使用 orient='records' 读取
df = pd.read_json(json_data, orient='records')

print("--- 示例1:records 格式读取结果 ---")
print(df)
读取数据 read_json() 读取json文件

1、创建data.json,内容:

json 复制代码
[
    {"姓名": "张三",  "城市": "北京"},
    {"姓名": "李四", "年龄": 30, "城市": "上海"}
]

2、创建read_json_from_file.py,代码:

python 复制代码
import pandas as pd

# 直接把文件路径 'data.json' 传给 read_json,并指定 orient='records'
df = pd.read_json('data.json',orient='records')
print(df)
读取数据 read_json() 读取jsonl字符串

注:读取jsonl的时候要加lines=True表示这是个jsonl文件,要按行读取。

python 复制代码
import pandas as pd

jsonl_data = '''
{"姓名": "张三", "年龄": 25, "城市": "北京"}
{"姓名": "李四", "年龄": 30, "城市": "上海"}
{"姓名": "王五", "年龄": 28, "城市": "深圳"}
'''

# 2. 使用 lines=True 告诉 pandas 这是按行分隔的 JSON
df = pd.read_json(jsonl_data, lines=True,orient='records')

print("--- JSONL 字符串读取结果 ---")
print(df)
读取数据 read_json() 读取jsonl文件

1、创建data.jsonl,内容:

json 复制代码
{"姓名": "张三", "年龄": 25, "城市": "北京"}
{"姓名": "李四", "年龄": 30, "城市": "上海"}
{"姓名": "王五", "年龄": 28, "城市": "深圳"}

代码:

python 复制代码
import pandas as pd

df = pd.read_json('data.jsonl', lines=True,orient='records')
print("--- JSONL 字符串读取结果 ---")
print(df)
orient='records'是什么意思?

读取和转换的时候,显示的指定,请按照标准的Key-Value(键值对)格式来处理每一条数据记录。

pandas支持复杂结构的json吗?

最好是行列结构,如果比较复杂,需要结合其他手法,如json_normalize()等。

json_normalize

json_normalize直接拍扁
python 复制代码
import pandas as pd
from pandas import json_normalize

data = {
    "id": 1,
    "name": "Alice",
    "info": {"age": 25, "city": "Beijing"}
}

# 直接展平
df = json_normalize(data)
print(df)
# 输出列名: id, name, info.age, info.city
json_normalize-结合record_path、meta

record_path(指定列表在哪里)和 meta(保留外层信息):

python 复制代码
from pandas import json_normalize

data = [
  {
    "user_id": 101,
    "profile": {"name": "Bob"},
    "orders": [
      {"product": "Book", "price": 20},
      {"product": "Pen", "price": 2}
    ]
  }
]

# record_path: 指向那个"列表"字段,这会让每一行变成一个订单
# meta: 把上层的 ID 和名字"提"出来,拼接到每一行
df = json_normalize(
    data,
    record_path='orders',
    meta=['user_id', ['profile', 'name']] # 嵌套字段要用列表表示路径
)

print(df)

输出结果:

python 复制代码
    product  price user_id profile.name
0    Book     20     101          Bob
1     Pen      2     101          Bob
相关推荐
HERR_QQ1 小时前
端到端课程自用 4 规划 基于自规划AR的端到端规划 AI 笔记
人工智能·笔记·自动驾驶·transformer
二哈赛车手2 小时前
新人笔记---实现简易版的rag的bm25检索(利用ES),以及RAG上传时的ES与向量数据库双写
java·数据库·笔记·spring·elasticsearch·ai
qiaozhangchi2 小时前
求解器学习笔记
笔记·python·学习
不会编程的懒洋洋2 小时前
C# P/Invoke 基础
开发语言·c++·笔记·安全·机器学习·c#·p/invoke
xian_wwq3 小时前
【学习笔记】网络与数据安全领域强制性标准
笔记·学习
24白菜头3 小时前
【无标题】
c++·笔记·学习·harmonyos
suirosu3 小时前
痛风高尿酸血症的治疗方法
笔记·其他·微信·新浪微博
余生皆假期-3 小时前
YuanHub 源码分析【一】FlashDB 初始化与项目应用
笔记·单片机·嵌入式硬件
做cv的小昊4 小时前
【TJU】研究生应用统计学课程笔记(6)——第二章 参数估计(2.4 区间估计)
人工智能·笔记·线性代数·算法·机器学习·数学建模·概率论