拆分(split)将长字符串解析为结构化的多列;连接(cat / join)则将多个字段合并为单一文本。二者是文本结构化的核心操作。


1. 按分隔符拆分:str.split()

基本用法

s = pd.Series(['2024-01-01', '2024-02-15', '2024-03-30'])
 
# 默认返回 Series of list
s.str.split('-')
# 0    [2024, 01, 01]
# 1    [2024, 02, 15]
# 2    [2024, 03, 30]

expand=True:展开为多列 DataFrame

s.str.split('-', expand=True)
#       0    1    2
# 0  2024   01   01
# 1  2024   02   15
# 2  2024   03   30

n 参数:限制拆分次数

s.str.split('-', n=1, expand=True)
#       0        1
# 0  2024  01-01
# 1  2024  02-15
# 2  2024  03-30

参数详解

参数说明
pat分隔符,默认空白;正则可用
n最大拆分次数(-1 表示不限制)
expand是否返回 DataFrame(默认 False)
regex是否将 pat 作为正则
# 正则拆分(按逗号或分号)
s = pd.Series(['a,b;c', 'x;y,z'])
s.str.split(r'[,;]', expand=True)

拆分后取指定位置

s.str.split('-').str[0]      # 取第 0 个分量
s.str.split('-').str.get(1)  # 取第 1 个分量
s.str.split('-', expand=True)[2]  # DataFrame 模式下取列

2. 从右拆分:str.rsplit()

s = pd.Series(['a-b-c-d', 'x-y-z'])
 
s.str.rsplit('-', n=1, expand=True)
#       0     1
# 0  a-b-c    d
# 1    x-y    z

split vs rsplit

  • split 从左到右拆分
  • rsplit 从右到左拆分,通常与 n=1 配合用于提取最后一段

3. 合并为新列:str.cat()

连接整个 Series

s = pd.Series(['a', 'b', 'c'])
 
s.str.cat(sep=', ')
# 'a, b, c'

与另一个 Series 逐行连接

df = pd.DataFrame({'姓': ['张', '李'], '名': ['三', '四']})
 
df['姓名'] = df['姓'].str.cat(df['名'], sep='')
#   姓  名  姓名
# 0  张  三   张三
# 1  李  四   李四

与其他列列表连接

df['姓名'] = df['姓'].str.cat(df[['姓', '名']], sep=' ')

缺失值处理

s1 = pd.Series(['a', None, 'c'])
s2 = pd.Series(['x', 'y', 'z'])
 
# 默认 na_rep=None:跳过缺失
s1.str.cat(s2, sep='-')
# 0    a-x
# 1    None
# 2    c-z
 
# 指定缺失值表示
s1.str.cat(s2, sep='-', na_rep='?')
# 0    a-x
# 1    ?-y
# 2    c-z

join 参数

# join='left':按左对象索引对齐(默认)
# join='right' / 'outer' / 'inner':其他对齐方式
s1.str.cat(s2, sep='-', join='inner')

cat 参数总览

参数说明
others要连接的 Series 或 Series 列表
sep连接符
na_rep缺失值的替代文本
join对齐方式:'left'、'right'、'outer'、'inner'

4. 列表元素连接:str.join()

str.join() 对每个元素(必须是列表/元组)执行 分隔符.join(列表)。

s = pd.Series([['a', 'b', 'c'], ['x', 'y']])
 
s.str.join('-')
# 0    a-b-c
# 1      x-y

注意

str.join 是 Series 内每个元素为列表时的连接;str.cat 是 Series 之间的连接。两者易混淆。


5. 使用 Python 运算合并列

df = pd.DataFrame({'省': ['广东', '江苏'], '市': ['广州', '南京']})
 
df['地址'] = df['省'] + '省' + df['市'] + '市'
#   省   市      地址
# 0  广东  广州  广东省广州市
# 1  江苏  南京  江苏省南京市
 
# 多列合并
df['完整'] = df['省'] + df['市']

性能比较

  • 普通列拼接使用 + 运算符即可,简单直观
  • 涉及缺失值处理建议使用 str.cat(na_rep='')
  • + 在任一列含 NaN 时结果为 NaN,str.cat 则可通过 na_rep 控制

6. 分割与展开的典型场景

场景 1:从完整地址拆分省市

df = pd.DataFrame({'地址': ['北京市朝阳区', '上海市浦东新区']})
 
df[['市', '区']] = df['地址'].str.extract(r'(.+?[市])(.+?[区])')

场景 2:从日期字符串拆分年月日

df = pd.DataFrame({'日期': ['2024-01-15', '2025-06-30']})
df[['年', '月', '日']] = df['日期'].str.split('-', expand=True)
df['年'] = pd.to_numeric(df['年'])

场景 3:从带分隔符的记录中提取关键字段

logs = pd.Series(['INFO|2024-01-01|用户登录', 'ERROR|2024-02-01|数据库连接失败'])
df = logs.str.split('|', expand=True)
df.columns = ['级别', '时间', '消息']

小结

  • 拆分:split / rsplit,expand=True 返回 DataFrame
  • 连接:str.cat 连接多个 Series,str.join 连接列表元素
  • 普通列拼接用 +,需处理缺失值时用 str.cat(na_rep=...)
  • 拆分常用于字段展开,连接常用于字段合并