
在实际数据处理中,我们经常会遇到某一列数据中包含混合类型信息的情况,例如数字和文本混杂在一起,且格式不统一。一个典型的例子是销售数据,其中销售数量可能被描述为“1 table”、“3chairs”或“8 cushions”,数字与单位紧密相连,且单位词汇不固定。为了对这些销售数量进行统计分析(如按类别求和),我们首先需要将这些数字从字符串中精确地提取出来。
假设我们有以下Pandas DataFrame:
import pandas as pd import io data = """Category Sales Paid Table 1 table Yes Chair 3chairs Yes Cushion 8 cushions Yes Table 3Tables Yes Chair 12 Chairs No Mats 12Mats Yes """ df = pd.read_csv(io.StringIO(data), sep=r'\s+') print(df)
输出:
Category Sales Paid 0 Table 1 table Yes 1 Chair 3chairs Yes 2 Cushion 8 cushions Yes 3 Table 3Tables Yes 4 Chair 12 Chairs No 5 Mats 12Mats Yes
我们的目标是从Sales列中提取纯数字,并按Category列进行分组求和。
Pandas提供了一个强大的字符串处理方法str.extract,它允许我们使用正则表达式从字符串中提取匹配的模式。
首先,我们需要定义一个正则表达式来匹配字符串开头的数字。正则表达式^(\d+)的含义如下:
我们将这个正则表达式应用于Sales列,并设置expand=False,这样str.extract会返回一个Series而不是DataFrame。
# 提取Sales列开头的数字
extracted_numbers = df['Sales'].str.extract('^(\d+)', expand=False)
print("提取出的原始数字字符串:")
print(extracted_numbers)输出:
提取出的原始数字字符串: 0 1 1 3 2 8 3 3 4 12 5 12 Name: Sales, dtype: object
此时,提取出的数字仍然是字符串类型(dtype: object)。为了进行数学运算,我们需要将其转换为整数类型。
使用astype(int)将提取出的字符串数字转换为整数:
# 转换为整数类型
numeric_sales = extracted_numbers.astype(int)
print("\n转换为整数后的数字:")
print(numeric_sales)输出:
转换为整数后的数字: 0 1 1 3 2 8 3 3 4 12 5 12 Name: Sales, dtype: int64
现在我们有了纯数字的numeric_sales Series,可以结合原始DataFrame的Category列进行分组求和了。
# 按Category分组求和
total_sales_per_category = numeric_sales.groupby(df['Category']).sum()
print("\n按类别汇总的总销售额:")
print(total_sales_per_category)输出:
按类别汇总的总销售额: Category Chair 15 Cushion 8 Mats 12 Table 4 Name: Sales, dtype: int64
有时,我们可能需要根据额外的条件进行聚合,例如只计算“Paid”状态为“Yes”的销售额。在这种情况下,我们可以在提取数字之前先对数据进行筛选或条件性处理。
Pandas的where方法非常适合这种场景。它根据条件选择Series中的元素,不满足条件的元素会被替换为指定的值(默认为NaN)。在这里,我们将不满足“Paid”为“Yes”的Sales值替换为字符串“0”,这样在后续提取和转换时,这些项会变成数字0,而不会影响总和。
# 只计算Paid为'Yes'的销售额
paid_sales_only = df['Sales'].where(df['Paid'] == 'Yes', other='0')
# 对处理后的列再次提取数字并转换为整数
numeric_paid_sales = paid_sales_only.str.extract('^(\d+)', expand=False).astype(int)
# 按Category分组求和
paid_sales_per_category = numeric_paid_sales.groupby(df['Category']).sum()
print("\n按类别汇总的已支付销售额:")
print(paid_sales_per_category)输出:
按类别汇总的已支付销售额: Category Chair 3 Cushion 8 Mats 12 Table 4 Name: Sales, dtype: int64
通过where(df['Paid'] == 'Yes', other='0')这一步,当Paid列不是'Yes'时,对应的Sales值(例如12 Chairs)会被替换为'0'。这样,在后续的str.extract和astype(int)操作中,这些项就会被正确地转换为数字0,从而只统计了已支付的销售额。
本教程演示了如何利用Pandas的str.extract方法结合正则表达式,有效地从格式不一致的字符串列中提取数值。通过将提取出的数据转换为适当的数值类型,并结合groupby()进行聚合,我们可以轻松地对非结构化数据进行清洗、转换和分析。这种技术在处理日志文件、网络爬取数据或任何包含混合文本和数字的数据集时都非常有用。掌握str.extract和正则表达式将大大提升你在Pandas中处理复杂字符串数据的能力。
以上就是Pandas数据清洗:从不规则字符串中提取数字并分组聚合的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号