
本教程详细介绍了如何使用Pandas库高效处理包含混合数据类型(数字词汇和数值)的DataFrame列。文章将重点讲解如何通过正则表达式进行复杂的数据拆分,识别并有条件地将数字词汇转换为数值,并最终将处理后的数据整合到新的结构化列中,以解决数据清洗中常见的格式不一致问题。
在数据分析和处理中,我们经常会遇到包含非标准格式数据的列,例如一列中混合了文本描述的数字(如“three hundred and two”)和常规数值(如“203.0”),并且这些数据可能由多种分隔符连接。本教程将指导您如何使用Pandas结合正则表达式和word2number库来解决这类复杂的数据清洗任务,最终将原始列拆分为多个结构化、数值化的新列。
假设我们有一个DataFrame,其中包含类似cement_water和coarse_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!。
为了有效解决上述问题,我们将采取以下策略:
首先,导入必要的库并创建示例DataFrame:
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)cement_water 列是挑战最大的部分,因为它混合了数字词汇和数值,并且可能使用不同的分隔符。我们将使用正则表达式来捕获两部分数据,然后对第一部分进行条件性转换。
使用正则表达式提取: 我们使用 str.extract() 配合正则表达式 r'(?P<cement>.*)[;,_](?P<water>\d+.?\d*)$'。
条件性转换 cement 部分:
# 提取 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)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)最后,我们将 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)将上述步骤整合在一起,形成一个完整的解决方案:
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)通过本教程,您应该能够掌握在Pandas中处理复杂混合数据类型、进行条件性数据转换以及利用正则表达式进行高效数据拆分的方法。这些技术在实际数据清洗工作中非常实用。
以上就是使用Pandas和正则表达式处理混合数据类型并转换数字词汇的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号