使用Pandas和正则表达式处理混合数据类型并转换数字词汇

心靈之曲
发布: 2025-11-07 11:53:01
原创
543人浏览过

使用pandas和正则表达式处理混合数据类型并转换数字词汇

本教程详细介绍了如何使用Pandas库高效处理包含混合数据类型(数字词汇和数值)的DataFrame列。文章将重点讲解如何通过正则表达式进行复杂的数据拆分,识别并有条件地将数字词汇转换为数值,并最终将处理后的数据整合到新的结构化列中,以解决数据清洗中常见的格式不一致问题。

在数据分析和处理中,我们经常会遇到包含非标准格式数据的列,例如一列中混合了文本描述的数字(如“three hundred and two”)和常规数值(如“203.0”),并且这些数据可能由多种分隔符连接。本教程将指导您如何使用Pandas结合正则表达式和word2number库来解决这类复杂的数据清洗任务,最终将原始列拆分为多个结构化、数值化的新列。

1. 问题描述与挑战

假设我们有一个DataFrame,其中包含类似cement_water和coarse_fine_aggregate这样的列。这些列的特点是:

  • 混合数据类型:cement_water列可能包含数字词汇(如"three hundred and two")和浮点数(如"203.0")。
  • 多重分隔符:不同行的数据可能使用不同的分隔符(例如;、,、_)来连接不同的数值。
  • 目标:将这些混合格式的列拆分为独立的、纯数值的列(例如cement、water、coarse_aggregate、fine_aggregate)。

原始数据示例:

cement_water coarse_fine_aggregate
three hundred and two;203.0 974.0,817.0
one hundred and fifty-one;184.4 992.0;815.9
three hundred and sixty-two_164.9 944.7;755.8

期望输出:

cement water coarse_aggregate fine_aggregate
302.0 203.0 974.0 817.0
151.0 184.4 992.0 815.9
362.0 164.9 944.7 755.8

直接使用简单的字符串分割和word2number转换可能会导致错误,特别是当word2number尝试转换一个已经是数字字符串(如"203.0")时,会抛出ValueError: No valid number words found!。

2. 解决方案概述

为了有效解决上述问题,我们将采取以下策略:

  1. 使用正则表达式提取数据:利用正则表达式的强大功能,一次性从原始字符串中提取出我们需要的各个部分,同时处理多种分隔符。
  2. 条件性地转换数字词汇:识别出哪些部分是数字词汇需要转换,哪些部分已经是数值字符串可以直接解析。
  3. 整合与类型转换:将提取和转换后的数据合并到新的DataFrame中,并确保所有列都转换为正确的数值类型。

3. 实现步骤与代码示例

首先,导入必要的库并创建示例DataFrame:

怪兽AI数字人
怪兽AI数字人

数字人短视频创作,数字人直播,实时驱动数字人

怪兽AI数字人 44
查看详情 怪兽AI数字人
import pandas as pd
from word2number import w2n
import io

# 示例数据
data = """cement_water,coarse_fine_aggregate
three hundred and two;203.0,974.0,817.0
one hundred and fifty-one;184.4,992.0;815.9
three hundred and sixty-two_164.9,944.7;755.8
"""
df = pd.read_csv(io.StringIO(data))

print("原始DataFrame:")
print(df)
登录后复制

3.1 处理 cement_water 列:提取并有条件转换

cement_water 列是挑战最大的部分,因为它混合了数字词汇和数值,并且可能使用不同的分隔符。我们将使用正则表达式来捕获两部分数据,然后对第一部分进行条件性转换。

  1. 使用正则表达式提取: 我们使用 str.extract() 配合正则表达式 r'(?P<cement>.*)[;,_](?P<water>\d+.?\d*)$'。

    • (?P<cement>.*):捕获分隔符前的所有字符作为 cement 部分。
    • [;,_]:匹配任意一个分隔符(分号、逗号、下划线)。
    • (?P<water>\d+.?\d*):捕获分隔符后的数字(整数或浮点数)作为 water 部分。
    • $:确保匹配到字符串的末尾。
  2. 条件性转换 cement 部分

    • 首先,尝试将提取出的 cement 部分直接转换为数值。如果失败(即它是一个数字词汇),则会产生 NaN。
    • 利用 pd.to_numeric(..., errors='coerce') 的特性,我们可以识别出哪些值是数字词汇(转换后为 NaN)。
    • 然后,只对这些 NaN 值对应的原始 cement 字符串应用 w2n.word_to_num 进行转换。
# 提取 cement_water 列
tmp = df['cement_water'].str.extract(r'(?P<cement>.*)[;,_](?P<water>\d+.?\d*)$')

# 尝试将 'cement' 列转换为数值,无法转换的会变成 NaN
s = pd.to_numeric(tmp['cement'], errors='coerce')

# 找出 'cement' 列中为 NaN 的行(即原始值是数字词汇的行)
# 并且确保原始值不是空的(因为 extract 可能会生成空字符串)
m = s.isna() & tmp['cement'].notna()

# 对这些行应用 w2n.word_to_num 进行转换
tmp.loc[m, 'cement'] = tmp.loc[m, 'cement'].map(w2n.word_to_num)

print("\n处理后的 tmp DataFrame (cement_water):")
print(tmp)
登录后复制

3.2 处理 coarse_fine_aggregate 列:简单拆分

coarse_fine_aggregate 列相对简单,它只包含数值,并由 ; 或 , 或 _ 分隔。我们可以直接使用 str.split()。

# 拆分 coarse_fine_aggregate 列
coarse_fine_agg = df['coarse_fine_aggregate'].str.split('[;,_]', expand=True)
# 重命名列
coarse_fine_agg = coarse_fine_agg.rename(columns={0: 'coarse_aggregate', 1: 'fine_aggregate'})

print("\n处理后的 coarse_fine_agg DataFrame:")
print(coarse_fine_agg)
登录后复制

3.3 合并结果并最终类型转换

最后,我们将 tmp 和 coarse_fine_agg 这两个处理过的DataFrame通过 pd.concat 合并起来,并将所有列转换为浮点数类型。

# 合并所有处理后的数据
out = pd.concat([tmp, coarse_fine_agg], axis=1)

# 将所有列转换为浮点数类型
out = out.astype(float)

print("\n最终转换后的DataFrame:")
print(out)
登录后复制

4. 完整代码示例

将上述步骤整合在一起,形成一个完整的解决方案:

import pandas as pd
from word2number import w2n
import io

# 示例数据
data = """cement_water,coarse_fine_aggregate
three hundred and two;203.0,974.0,817.0
one hundred and fifty-one;184.4,992.0;815.9
three hundred and sixty-two_164.9,944.7;755.8
"""
df = pd.read_csv(io.StringIO(data))

# 1. 处理 'cement_water' 列
# 提取 cement_water 列,捕获分隔符前后的内容
tmp = df['cement_water'].str.extract(r'(?P<cement>.*)[;,_](?P<water>\d+.?\d*)$')

# 尝试将 'cement' 列转换为数值,无法转换的会变成 NaN
s = pd.to_numeric(tmp['cement'], errors='coerce')

# 找出 'cement' 列中为 NaN 的行(即原始值是数字词汇的行)
m = s.isna() & tmp['cement'].notna()

# 对这些行应用 w2n.word_to_num 进行转换
tmp.loc[m, 'cement'] = tmp.loc[m, 'cement'].map(w2n.word_to_num)

# 2. 处理 'coarse_fine_aggregate' 列
# 拆分 coarse_fine_aggregate 列,支持多种分隔符
coarse_fine_agg = df['coarse_fine_aggregate'].str.split('[;,_]', expand=True)
# 重命名列
coarse_fine_agg = coarse_fine_agg.rename(columns={0: 'coarse_aggregate', 1: 'fine_aggregate'})

# 3. 合并结果并转换为浮点数
out = pd.concat([tmp, coarse_fine_agg], axis=1)
out = out.astype(float)

print("最终处理结果:")
print(out)
登录后复制

5. 注意事项与总结

  • 正则表达式的精准性:选择合适的正则表达式至关重要。r'(?P<cement>.*)[;,_](?P<water>\d+.?\d*)$' 能够灵活处理多种分隔符,并确保 water 部分是数字。
  • pd.to_numeric(errors='coerce') 的妙用:这是识别混合数据类型中哪些是数字词汇的关键。它允许我们只对需要转换的部分应用 w2n.word_to_num,从而避免 ValueError。
  • 链式操作与可读性:虽然可以将所有操作链式组合起来,但为了教程的清晰性,这里分步进行了展示。在实际生产代码中,可以根据团队规范和复杂性进行调整。
  • 错误处理:本教程假设数据格式基本符合预期。在更复杂的场景中,您可能需要添加额外的错误处理逻辑,例如当正则表达式无法匹配任何数据时。
  • 库依赖:确保您的环境中安装了 pandas 和 word2number 库 (pip install pandas word2number)。

通过本教程,您应该能够掌握在Pandas中处理复杂混合数据类型、进行条件性数据转换以及利用正则表达式进行高效数据拆分的方法。这些技术在实际数据清洗工作中非常实用。

以上就是使用Pandas和正则表达式处理混合数据类型并转换数字词汇的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号