自学教程 学编程从这里开始

Pandas 字符串处理

Pandas 字符串处理 str 访问器

承接上一篇《Pandas 缺失值处理》,本篇讲解 Pandas str 访问器,专门用于 Series 文本批量处理,包含判断、截取、替换、分割、正则、清洗、提取,同时标注坑点:str 仅支持 string / object 类型,category 分类列需要先转换。保持系列教程统一风格。
前置导入与示例数据

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "name": ["张三", "李四", "王五", "赵六", "孙七", " 周八 ", "Tom_99", None],
    "phone": ["13800138000", "13900139000", "13700137000", "13600136000", "", "13500135000", "13400134000", pd.NA],
    "email": ["zhangsan@abc.com", "lisi@abc.com", "wangwu@xyz.org", "zhaoliu@abc.com", "sunqi@test.cn", "zhouba@abc.com", "tom99@xyz.com", pd.NA],
    "address": ["浙江省杭州市西湖区", "上海市浦东新区", "浙江省杭州市余杭区", "北京市朝阳区", "浙江省宁波市鄞州区", "广东省深圳市南山区", "杭州市滨江区", pd.NA]
})
print(df)

一、基础说明

str 访问器是 Pandas 给文本 Series 提供的批量字符串方法,相当于内置字符串函数的向量化版本,不用循环。
⚠️ 重要前提:

  1. 列类型为 object 或者 string(推荐新版 string 类型)
  2. Categorical 类别列不能直接使用 .str,需要先 astype("string")
  3. 遇到缺失值 pd.NA / None,默认返回 NA;大部分方法支持 na=False 参数
# 转为 string 类型(推荐,对空值友好)
df["name"] = df["name"].astype("string")

二、空白处理(清洗高频)

# 去除左右空格
df["name"].str.strip()
# 只去除左侧空格
df["name"].str.lstrip()
# 只去除右侧空格
df["name"].str.rstrip()

# strip 支持自定义字符
df["name"].str.strip("_ ")

三、判断匹配:contains / startswith / endswith

返回布尔 Series,常配合 loc 过滤

# 包含指定文本,na=False 空值返回False,避免报错
df["address"].str.contains("杭州", na=False)
# 以指定字符开头
df["email"].str.startswith("zhang", na=False)
# 以指定字符结尾
df["email"].str.endswith("@abc.com", na=False)

# 正则匹配,开启正则
df["email"].str.contains(r"^zh.*@", regex=True, na=False)

四、大小写转换

df["email"].str.upper()    # 全部大写
df["email"].str.lower()    # 全部小写
df["email"].str.capitalize() # 首字母大写,其余小写

五、截取字符:slice / []

# 截取前3个字符
df["phone"].str.slice(0, 3)
# 等价写法
df["phone"].str[0:3]

# 从倒数4位开始(手机号后4位)
df["phone"].str[-4:]

六、替换 replace

支持普通文本替换 + 正则替换

# 普通替换
df["address"].str.replace("浙江省", "浙", regex=False)
# 正则替换:把数字全部替换成*
df["name"].str.replace(r"\d", "*", regex=True)

Pandas 2.0+ 默认 regex=False,老版本默认True,建议显式写参数避免歧义。

七、分割 split 拆分字符串

# 按下划线分割,返回列表
df["name"].str.split("_")
# 分割后取第0段
df["name"].str.split("_").str[0]
# 分割并且展开成多列,expand=True
df["email"].str.split("@", expand=True)

八、提取正则 extract(业务神器)

从文本里按正则分组提取内容,非常适合提取手机号、编号、域名

# 提取邮箱用户名和域名
df["email"].str.extract(r"(.+)@(.+)\.(.+)")
  • 正则里 () 代表分组,每个分组对应输出一列
  • 匹配失败返回 NA

九、拼接、计数、长度

# 字符串长度
df["name"].str.len()
# 统计某个字符出现次数
df["email"].str.count(r"@")
# 拼接固定前缀
"prefix_" + df["name"].str.lower()

十、填充、对齐、补齐

# 左对齐,总长度10,不足补空格
df["name"].str.ljust(10)
# 右对齐,总长度10,不足补0(编号补零常用)
df["phone"].str.rjust(11, fillchar="0")
# 居中对齐
df["name"].str.center(10)
# zfill 从左侧补0
df["phone"].str.zfill(11)

十一、字符串布尔判断方法

# 是否全数字
df["phone"].str.isdigit()
# 是否全字母
df["name"].str.isalpha()
# 是否字母+数字
df["name"].str.isalnum()
# 是否空白字符
df["name"].str.isspace()

十二、get 取出列表元素

split 之后得到列表,可以用 .str.get(n) 取出第n个元素,等价 .str[n]

df["email"].str.split("@").str.get(0)

十三、链式清洗示例

res = df["address"].str.strip()\
    .str.replace("浙江省", "浙", regex=False)\
    .str.replace("上海市", "沪", regex=False)\
    .str.contains("杭州", na=False)

十四、常用参数说明

  • na=False:判断类方法(contains、startswith),NA行返回False,防止报错
  • expand=True:split 拆分后展开为多列DataFrame
  • regex=True:开启正则模式
  • pat:匹配模板
  • repl:替换内容

十五、高频坑清单

  1. ❌ category 类型直接调用 .str → 报错,先 astype("string")
  2. ❌ 有空值不写 na=False,contains 直接抛出异常
  3. ❌ replace 忘记 regex=False,特殊字符 . * + 被当成正则
  4. ❌ str.len() 对 pd.NA 返回NA,不是0
  5. ❌ split 之后直接取元素,没有 .str,df["col"].split("_")[0] 是错误写法
  6. ❌ 空字符串 "" 不是 pd.NA,str.isspace() 可以识别空白字符串

十六、综合实战模板

def clean_text_series(s: pd.Series) -> pd.Series:
    """文本清洗流水线:去空格、转string、空文本转为pd.NA"""
    s = s.astype("string").str.strip()
    s = s.replace(r"^\s*$", pd.NA, regex=True)
    return s

# 提取手机号前3位
df["phone_prefix"] = clean_text_series(df["phone"]).str[:3]
# 提取邮箱域名
df["email_domain"] = clean_text_series(df["email"]).str.extract(r"@(.+)$")[0]
print(df[["phone","phone_prefix","email","email_domain"]])

十七、API速查表

API作用
str.strip()去除两端空白
str.contains()包含匹配,支持正则
str.startswith / endswith前缀、后缀匹配
str.slice / str[]字符截取
str.replace()文本替换
str.split(expand=True)分割展开多列
str.extract()正则分组提取
str.len()获取字符串长度
str.isdigit / isalpha字符类型判断
str.lower / upper大小写转换
str.zfill / rjust补零对齐
标签:

0 条笔记