文本数据常需要与其他类型互转,或进行编码、哑变量化等处理。本节覆盖字符串与数值/日期/布尔之间的转换,以及文本编码与分类编码。


1. 数值转字符串

astype 转换

s = pd.Series([1, 2, 3])
 
s.astype(str)
# 0    '1'
# 1    '2'
# 2    '3'
 
# string 扩展类型
s.astype('string')

格式化转换

# 添加千位分隔符
s = pd.Series([1234567, 8901234])
s.astype(str)
# 0    '1234567'
 
# 使用 apply 自定义格式
s.apply(lambda x: f"{x:,}")
# 0    '1,234,567'
# 1    '8,901,234'
 
# 固定小数位
prices = pd.Series([1.5, 2.345])
prices.apply(lambda x: f"{x:.2f}")
# 0    '1.50'
# 1    '2.35'

2. 字符串转数值

pd.to_numeric()

s = pd.Series(['1', '2.5', '3,000', 'abc'])
 
pd.to_numeric(s.str.replace(',', ''), errors='coerce')
# 0      1.0
# 1      2.5
# 2   3000.0
# 3      NaN

百分比转小数

s = pd.Series(['10%', '25.5%', '100%'])
 
s.str.rstrip('%').astype(float) / 100
# 0    0.100
# 1    0.255
# 2    1.000

货币字符串转数值

s = pd.Series(['$1,234.56', '$999.99'])
 
s.str.replace(r'[$,\s]', '', regex=True).astype(float)
# 0    1234.56
# 1     999.99

3. 字符串与日期互转

字符串转日期

s = pd.Series(['2024-01-01', '2024/02/15'])
 
pd.to_datetime(s)
# 0   2024-01-01
# 1   2024-02-15
# dtype: datetime64[ns]
 
# 指定格式
pd.to_datetime(s, format='%Y/%m/%d')

日期转字符串

dates = pd.Series(pd.date_range('2024-01-01', periods=3, freq='D'))
 
dates.dt.strftime('%Y-%m-%d')
# 0    '2024-01-01'
# 1    '2024-01-02'
# 2    '2024-01-03'
 
dates.dt.strftime('%Y年%m月%d日')
# 0    '2024年01月01日'

4. 字符串与布尔

字符串转布尔

s = pd.Series(['True', 'False', 'true', 'FALSE', None])
 
s.str.lower().map({'true': True, 'false': False})
# 0     True
# 1    False
# 2     True
# 3    False
# 4      NaN
 
# 更可靠:replace
s.str.title().replace({'True': True, 'False': False})

布尔转字符串

s = pd.Series([True, False, True])
 
s.astype(str)
# 0    'True'
# 1    'False'
# 2    'True'
 
# 自定义映射
s.map({True: '是', False: '否'})
# 0    是
# 1    否
# 2    是

5. 文本编码:str.encode() / str.decode()

encode

s = pd.Series(['中文', 'pandas'])
 
s.str.encode('utf-8')
# 0    b'\xe4\xb8\xad\xe6\x96\x87'
# 1    b'pandas'

decode

s_encoded = s.str.encode('utf-8')
s_encoded.str.decode('utf-8')
# 0    中文
# 1    pandas
编码说明
'utf-8'通用编码(推荐)
'gbk'中文编码
'gb2312'中文简化编码
'latin1'西欧编码
'ascii'ASCII

注意

解码失败时可能抛出异常,可通过 errors 参数控制(需 Python 3 原生 bytes 操作支持)。


6. 分类编码:factorize 与 get_dummies

pandas.factorize()

将文本类别映射为整数编码:

s = pd.Series(['北京', '上海', '北京', '广州'])
 
codes, uniques = pd.factorize(s)
print(codes)      # [0 1 0 2]
print(uniques)    # Index(['北京', '上海', '广州'])

str 相关:从编码恢复

pd.Series(codes).map(dict(enumerate(uniques)))
# 0    北京
# 1    上海
# 2    北京
# 3    广州

pd.get_dummies() 哑变量化

df = pd.DataFrame({'城市': ['北京', '上海', '北京', '广州']})
 
pd.get_dummies(df['城市'], prefix='城市')
#    城市_北京  城市_广州  城市_上海
# 0       1       0       0
# 1       0       0       1
# 2       1       0       0
# 3       0       1       0
 
# 保留前缀
pd.get_dummies(df, columns=['城市'], prefix='城市')
方法说明
pd.get_dummies(data)生成哑变量列
pd.factorize(values)整数编码
s.astype('category')分类类型,cat.codes 可查看编码

7. 字符串与分类类型互转

s = pd.Series(['低', '高', '中', '低'])
 
# 转分类
cat = s.astype('category')
print(cat.cat.categories)   # Index(['低', '中', '高'])
 
# 指定顺序
from pandas import CategoricalDtype
cat_type = CategoricalDtype(categories=['低', '中', '高'], ordered=True)
s.astype(cat_type)

小结

  • 转数值:astype / pd.to_numeric,注意先去货币、百分号、千分位
  • 转日期:pd.to_datetime,反向用 dt.strftime
  • 转布尔:replace 与字典映射
  • 编码:encode / decode
  • 哑变量化:pd.get_dummies、pd.factorize