新闻中心

Pandas数据清洗:高效处理混合分隔符与文本数字的列拆分与转换

2025-11-11
浏览次数:
返回列表

Pandas数据清洗:高效处理混合分隔符与文本数字的列拆分与转换

本教程旨在解决pandas数据处理中常见的挑战:如何将包含混合分隔符和文本(英文单词)表示数字的单列数据,拆分成多个独立的数值列。我们将探讨使用正则表达式提取数据、结合`word2number`库将文本数字转换为数值,并利用pandas的强大功能进行高效的数据清洗、类型转换与结构重塑,确保数据准确性和可用性。

在数据分析和机器学习项目中,原始数据往往不够规整。一个常见的问题是,单个列中可能包含由多种分隔符连接的多个逻辑值,并且这些值可能以文本(如“three hundred and two”)和数字(如“203.0”)的混合形式存在。本教程将指导您如何使用Python的Pandas库结合正则表达式和word2number库来高效地处理这类复杂的数据清洗任务。

问题场景描述

假设我们有一个DataFrame,其中包含类似cement_water和coarse_fine_aggregate这样的列。 cement_water列的值可能形如three hundred and two;203.0或one hundred and fifty-one;184.4,甚至three hundred and sixty-two_164.9。这里存在以下挑战:

  1. 混合分隔符: 值之间可能使用;、,或_等不同字符进行分隔。
  2. 文本数字: 部分数值以英文单词形式(如three hundred and two)存在,需要转换为实际的数字。
  3. 类型转换: 最终所有拆分出的列都应为数值类型。

我们的目标是将这些列转换为以下结构:

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

初始尝试与遇到的问题

许多用户在处理这类问题时,可能会尝试先统一分隔符,然后使用str.split()进行拆分,最后再对文本数字进行转换。

import pandas as pd
from word2number import w2n

# 假设df已加载
# df = pd.read_csv('your_data.csv')

# 模拟数据
data = {
    'cement_water': ['three hundred and two;203.0', 'one hundred and fifty-one;184.4', 'three hundred and sixty-two_164.9'],
    'coarse_fine_aggregate': ['974.0,817.0', '992.0;815.9', '944.7;755.8']
}
df = pd.DataFrame(data)

def convert_words_to_numbers(text):
    # 尝试统一分隔符并分割,然后转换
    # 这种方法存在问题,因为w2n.word_to_num不能处理纯数字字符串
    words = text.replace('_', ' ').replace(';', ' ').replace(',', ' ').split()
    converted_words = []
    for word in words:
        if word.isalpha(): # 如果是字母,尝试转换为数字
            converted_words.append(str(w2n.word_to_num(word)))
        else: # 否则直接添加
            converted_words.append(word)
    return ' '.join(converted_words)

# 应用转换函数
df['cement_water_processed'] = df['cement_water'].apply(lambda x: convert_words_to_numbers(x))

# 尝试拆分
# df[['cement', 'water']] = df['cement_water_processed'].str.split(' ', expand=True)
# 这段代码会因为w2n.word_to_num无法处理"203.0"等纯数字字符串而报错,
# 即使修改了convert_words_to_numbers函数,也可能因为分隔符处理不当导致问题。

上述代码尝试通过统一分隔符后进行split,并使用word2number转换。然而,w2n.word_to_num()函数设计用于将英文单词转换为数字,例如"two hundred",但它无法处理已经是数字格式的字符串,如"203.0"。如果尝试将"203.0"传递给w2n.word_to_num(),就会抛出ValueError: No valid number words found!。这表明我们需要更精细的策略来区分和处理文本数字和纯数字字符串。

解决方案:结合正则表达式与条件转换

为了解决上述问题,我们可以采用以下更健壮的方法:

  1. 使用正则表达式精确提取: 利用str.extract()结合正则表达式,可以同时处理多种分隔符,并区分文本部分和数字部分。
  2. 有条件地应用word2number: 仅对那些确实是文本数字的部分应用w2n.word_to_num()。
  3. 统一数据类型: 最终将所有目标列转换为浮点数。

方案一:针对特定模式的直接提取与转换

如果我们的数据模式相对固定,即一个文本数字后跟一个分隔符,再跟一个纯数字,可以使用如下正则表达式。

import pandas as pd
from word2number import w2n

# 模拟数据
data = {
    'cement_water': ['three hundred and two;203.0', 'one hundred and fifty-one;184.4', 'three hundred and sixty-two_164.9'],
    'coarse_fine_aggregate': ['974.0,817.0', '992.0;815.9', '944.7;755.8']
}
df = pd.DataFrame(data)

# 1. 使用正则表达式提取 cement_water 列
# (?P<cement>.*) 捕获分隔符前的所有内容作为 'cement'
# [;,_] 匹配任意一个分隔符
# (?P<water>\d+.?\d*)$ 捕获分隔符后的数字(整数或浮点数)作为 'water',并确保在行尾
tmp_cement_water = df['cement_water'].str.extract(r'(?P<cement>.*)[;,_](?P<water>\d+.?\d*)$')

# 2. 对 coarse_fine_aggregate 列进行拆分
# [;,_] 匹配任意一个分隔符进行拆分
tmp_coarse_fine = df['coarse_fine_aggregate'].str.split('[;,_]', expand=True) \
                                             .rename(columns={0: 'coarse_aggregate', 1: 'fine_aggregate'})

# 3. 将 'cement' 列的文本数字转换为数值
# 使用 .map() 配合 w2n.word_to_num 对 'cement' 列进行转换
tmp_cement_water['cement'] = tmp_cement_water['cement'].map(w2n.word_to_num)

# 4. 合并所有结果列并转换为浮点型
out = pd.concat([tmp_cement_water, tmp_coarse_fine], axis=1).astype(float)

print("方案一结果:")
print(out)

输出示例:

千鹿Pr助手 千鹿Pr助手

智能Pr插件,融入众多AI功能和海量素材

千鹿Pr助手 128 查看详情 千鹿Pr助手
   cement  water  coarse_aggregate  fine_aggregate
0   302.0  203.0             974.0           817.0
1   151.0  184.4             992.0           815.9
2   362.0  164.9             944.7           755.8

这个方案的关键在于正则表达式r'(?P.*)[;,_](?P\d+.?\d*)$',它能够将文本数字部分(cement)与纯数字部分(water)有效分离。这样,w2n.word_to_num只作用于它能够处理的文本数字。

方案二:更通用的条件转换(推荐)

在某些情况下,cement部分可能也混合了纯数字字符串(尽管本例中不是),或者数据模式更复杂。为了提高鲁棒性,我们可以采用一个更通用的方法,即先尝试将列转换为数字,失败后再使用word2number。

import pandas as pd
from word2number import w2n

# 模拟数据
data = {
    'cement_water': ['three hundred and two;203.0', 'one hundred and fifty-one;184.4', 'three hundred and sixty-two_164.9'],
    'coarse_fine_aggregate': ['974.0,817.0', '992.0;815.9', '944.7;755.8']
}
df = pd.DataFrame(data)

# 1. 使用正则表达式提取 cement_water 列
tmp = df['cement_water'].str.extract(r'(?P<cement>.*)[;,_](?P<water>\d+.?\d*)$')

# 2. 尝试将 'cement' 列直接转换为数值,无法转换的标记为 NaN
s = pd.to_numeric(tmp['cement'], errors='coerce')

# 3. 找出那些无法转换为数值(即为 NaN)且原始数据不为空的行
m = s.isna() & df['cement_water'].notna()

# 4. 仅对这些无法直接转换为数值的行,使用 w2n.word_to_num 进行转换
# 注意:这里假设tmp['cement']中m对应的元素是word string,如果不是,w2n.word_to_num会报错
# 实际上,由于前面的regex已经将纯数字部分提取给了'water',这里'cement'通常都是word string
tmp.loc[m, 'cement'] = df.loc[m, 'cement_water'].map(lambda x: w2n.word_to_num(x.split('[;,_]')[0]) if isinstance(x, str) else x)
# 修正:更准确的做法是使用tmp['cement']而不是df['cement_water'],因为tmp['cement']已经包含了提取出的word string
tmp.loc[m, 'cement'] = tmp.loc[m, 'cement'].map(w2n.word_to_num)


# 5. 对 coarse_fine_aggregate 列进行拆分
tmp_coarse_fine = df['coarse_fine_aggregate'].str.split('[;,_]', expand=True) \
                                             .rename(columns={0: 'coarse_aggregate', 1: 'fine_aggregate'})

# 6. 合并所有结果列并转换为浮点型
out = pd.concat([tmp, tmp_coarse_fine], axis=1).astype(float)

print("\n方案二结果:")
print(out)

输出示例:

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

方案二的优势在于其灵活性。它首先尝试最直接的数值转换,只有当转换失败时(说明是文本数字),才调用word2number。这避免了不必要的word2number调用,并能处理更复杂的数据混合情况。

关键注意事项与总结

  1. 正则表达式的精准性: 正则表达式是此解决方案的核心。r'(?Ppattern)'语法允许您命名捕获组,这使得后续处理更加方便。根据您的数据模式,可能需要调整正则表达式以精确匹配。例如,[;,_]可以匹配分号、逗号或下划线中的任意一个作为分隔符。\d+.?\d*用于匹配整数或浮点数。
  2. word2number库: 确保已安装word2number (pip install word2number)。它对于处理英文文本数字非常有效,但请记住它不能处理纯数字字符串。
  3. pd.to_numeric(errors='coerce'): 这是一个强大的工具,可以尝试将Series转换为数值类型。当遇到无法转换的值时,errors='coerce'参数会将其替换为NaN,这使得我们可以方便地识别并进一步处理这些异常值。
  4. 数据类型转换: 最终使用.astype(float)确保所有新生成的列都是浮点数类型,这对于后续的数值计算和分析至关重要。
  5. 性能考虑: 对于非常大的数据集,链式操作和多次apply可能会影响性能。上述解决方案中,通过矢量化的Pandas操作(如str.extract, str.split, map, pd.to_numeric, loc)可以获得较好的性能。
  6. 错误处理: 在实际应用中,如果word2number遇到它无法识别的文本(例如拼写错误或非数字文本),仍然可能抛出错误。您可能需要添加额外的错误捕获机制,例如在map函数中使用try-except块。

通过本教程,您应该能够熟练地处理Pandas中包含混合分隔符和文本数字的复杂列拆分与转换任务,从而为后续的数据分析奠定坚实的基础。

以上就是Pandas数据清洗:高效处理混合分隔符与文本数字的列拆分与转换的详细内容,更多请关注其它相关文章!


# 多个  # 狼雨seo 顾问  # SEO学习方法初中  # 微博营销软文推广文案  # 花都品牌网站推广哪个好  # 江津模板网站建设  # 彩妆类关键词排名大全  # 创业干货网站怎么做推广  # 没有技术如何做网站推广  # 焦作云鹿搜网站建设  # 新媒体营销推广班  # 链式  # 这类  # 浮点  # word  # 浮点数  # 我们可以  # 文档  # 分隔符  # 转换为  # gate  # red  # 数据清洗  # csv  # 工具  # app  # 正则表达式  # python 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 在J*a中如何捕获IndexOutOfBoundsException_索引越界异常防护方法说明  优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题  迅雷下载到U盘速度很慢怎么办_迅雷U盘下载慢优化方法  探索高级语言到C/C++的转译路径:以Go为例及内存管理策略  MAC的“快捷指令”怎么同步到iPhone_MAC利用iCloud同步所有设备的自动化指令  文心一言怎样用批量生成做多版文案_文心一言用批量生成做多版文案【批量创作】  小红书网页版入口链接分享 小红书官网直接进  QQ邮箱电脑版登录入口_QQ邮箱官方网站登录平台  C++ string find函数返回值npos详解_C++字符串查找失败的判断条件  在J*a中如何开发简易博客标签推荐系统_博客标签推荐项目实战解析  痛风发作了怎么办? 快速止痛和后期饮食调理  文心一言怎样用插件调度API数据_文心一言用插件调度API数据【API调用】  知乎APP怎么管理已购盐选内容_知乎APP盐选内容购买记录与查看方法  sublime如何处理大型CSV文件的列对齐_sublime高级表格编辑插件指南  Go语言中Map值调用指针接收器方法的限制与应对  J*aScript map 迭代中检测空数组元素的有效方法  Python中如何避免重复条件判断:利用数据结构实现动态逻辑  红果短剧网页版官网入口 官方最新网址发布  没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享  mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析  CSS Flexbox与媒体查询:实现响应式布局中元素的并排与堆叠  Lar*el如何生成PDF或Excel文件_Lar*el文档导出工具与使用教程  在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明  LINQ to XML为何解析失败? 深入理解C# XDocument的异常处理  CSS Flexbox如何实现多行排列_flex-wrap wrap自动换行显示  品牌机怎么重装系统 联想/戴尔/惠普笔记本恢复出厂系统教程  CSS Grid如何控制元素对齐_align-items与justify-items组合使用  如何高效处理PHP中的Excel数据导入导出?PortPHP/Spreadsheet助你轻松搞定!  深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现  Linux如何构建多环境配置管理_Linux多环境配置方案  Lar*el 递归关系中排除指定分支的教程  C++如何实现单例模式_C++设计模式之线程安全的单例写法  vivo手机互传视频怎么操作_vivo手机互传视频详细传输方法  Yandex搜索引擎官方地址 俄罗斯网络世界的主要入口  C++如何实现异步操作_C++11使用std::future和std::async进行异步编程  在Go Martini框架中高效服务动态生成图像的实践指南  神庙逃亡小游戏在线玩 神庙逃亡小游戏入口  漫蛙2网页版漫画入口 漫蛙漫画在线官方登录  夸克浏览器桌面版同步不了书签怎么处理 夸克浏览器跨设备同步异常解决方案  微信怎么把收藏的内容分类管理 微信收藏内容标签分类方法  WordPress插件开发:正确注册卸载钩子与避免常见陷阱  steam官方入口大全 steam账号注册及操作指南  抖音创作助手登录入口_抖音创作辅助工具官网直达  mcjs网页版流畅运行 mcjs低配电脑畅玩入口  千牛数据看板网页版_千牛数据看板网页版访问方法  PHP高效扁平化嵌套数组:使用array_merge与数组解包操作符  《铁拳8》黑皮辣妹新实机:元气满满的18岁少女!  漫蛙2在线漫画入口 漫蛙正版漫画网页版直达  微博网页版首页入口 微博电脑端官网登录链接  如何使 Jest 模拟函数默认抛出错误以提高测试效率 

搜索