Pandas中处理对象类型数据并计算均值:从数据清洗到数值分析

聖光之護
发布: 2025-11-21 14:50:20
原创
371人浏览过

Pandas中处理对象类型数据并计算均值:从数据清洗到数值分析

在pandas数据分析中,当包含数值和单位的列被错误识别为“对象”类型时,直接计算均值等统计量会受阻。本教程详细介绍了如何通过系统性的数据清洗和类型转换,将这些“对象”列精确地转换为数值类型,从而实现准确的描述性统计分析,包括处理缺失值、单位转换、分隔符统一及异常值处理,最终计算出有效的统计指标。

引言

在数据预处理阶段,我们经常会遇到Pandas DataFrame中某些本应是数值型的列被错误地识别为object(对象)类型的情况。这通常是由于数据中混杂了文本(如单位、描述性文字)、特殊字符(如逗号作为小数点)、空格或多种数据格式。当这些列被标记为object类型时,我们无法直接使用mean()、median()等数值统计函数来计算它们的中心趋势度量。本教程将指导您如何识别这类问题,并提供一套系统性的方法来清洗和转换这些object类型数据,使其能够进行准确的数值分析。

识别问题:对象类型中的数值数据

首先,我们需要了解数据集中哪些列是object类型,以及它们内部的数据结构。通过df.info()和df.head()可以初步检查数据类型和前几行数据,从而发现潜在的问题。

假设我们有一个名为data.xlsx的数据集,其中包含笔记本电脑的各种属性,例如Memory Speed、Device Weight、Screen Size、Max Processor Speed、RAM (System Memory)和SSD Capacity等。

import pandas as pd
import numpy as np

# 加载数据集
dataset = pd.read_excel('data.xlsx')

# 查看数据集信息
print("--- 原始数据集信息 ---")
print(dataset.info())

# 查看数据集前几行
print("\n--- 原始数据集前5行 ---")
print(dataset.head())
登录后复制

从dataset.info()的输出中,我们可以看到许多列,如Memory Speed、Device Weight、Screen Size等,都被识别为object类型。而dataset.head()的输出则揭示了这些object列中包含的实际数据:例如Memory Speed可能包含“2666 MHz”,Device Weight包含“2 - 4 kg”,Screen Size包含“15.6 inches”,SSD Capacity包含“256 GB”或“1 TB”。这些都是带有单位的数值,或者包含范围、特殊分隔符的数值。

直接对这些object列使用describe()函数(即使include='all')也无法提供准确的数值统计信息,因为它会将它们视为分类数据。

# 尝试使用describe(include='all')查看原始数据集的描述性统计
print("\n--- 原始数据集的描述性统计 (include='all') ---")
print(dataset.describe(include="all"))
登录后复制

此时,对于object类型的列,describe()只会给出count、unique、top和freq等信息,而不会计算均值、标准差等数值统计量。

落笔AI
落笔AI

AI写作,AI写网文、AI写长篇小说、短篇小说

落笔AI 41
查看详情 落笔AI

解决方案:系统性的数据清洗与类型转换

要计算这些“对象”类型列的均值,我们必须将其转换为数值类型。这需要一个逐列、逐值的细致处理过程,以应对数据中的各种复杂情况。

核心转换逻辑

我们将遍历DataFrame中的每一列。如果一列是object类型,我们将对其进行以下处理:

  1. 处理缺失值 (NaN):如果值是NaN,则直接保留为NaN。
  2. 检测并分离数值与单位:检查值中是否包含空格。如果包含,通常意味着数值和单位是分开的(例如 "15.6 inches")。我们将尝试将值按空格分割。
  3. 处理小数点分隔符:在某些地区,逗号(,)被用作小数点。如果分割后的数值部分包含逗号,需要将其替换为英文句号(.)。
  4. 单位标准化:对于某些列,如SSD Capacity,单位可能不一致(例如GB和TB)。需要将所有单位统一到某个基准(例如,将TB转换为GB,或将GB转换为TB)。
  5. 尝试转换为浮点数:使用try-except块尝试将处理后的数值部分转换为float类型。如果转换失败(例如,值是“High”、“Low”或“1920 x 1080”这样的纯文本或复杂字符串),则保留其原始字符串形式。
  6. 处理不含空格或无法转换的值:如果值不含空格,或者经过分割处理后仍无法转换为数值,则保留其原始形式。

示例代码实现

# 创建一个新的DataFrame用于存储清洗后的数据
df_cleaned = pd.DataFrame(columns=dataset.columns)

for col in dataset.columns: # 遍历每一列
    if dataset[col].dtypes == "object": # 如果列的数据类型是'object'
        values = [] # 初始化一个空列表来存储处理后的值
        for val in dataset[col].values: # 遍历列中的每一个值
            if pd.isna(val): # 如果值是NaN
                values.append(np.nan) # 添加NaN
            elif isinstance(val, (int, float)): # 如果值已经是数字类型(即使列是object,也可能有个别是数字)
                values.append(float(val))
            elif " " in str(val): # 如果值中包含空格(通常表示数值和单位)
                val_splitted = str(val).split(" ") # 按空格分割

                # 检查并替换逗号为小数点
                if "," in val_splitted[0]:
                    val_splitted[0] = val_splitted[0].replace(",", ".")

                if len(val_splitted) == 2: # 如果分割后只有两部分(数值和单位)
                    try:
                        # 特殊处理 'SSD Capacity' 列,统一单位
                        if col == "SSD Capacity":
                            if val_splitted[1].upper() == "GB": # 如果单位是GB
                                values.append(float(val_splitted[0]) / 1000) # 转换为TB
                            elif val_splitted[1].upper() == "TB": # 如果单位是TB
                                values.append(float(val_splitted[0])) # 直接使用
                            else: # 其他未知单位,保留原值
                                values.append(val)
                        # 特殊处理 'Device Weight' 列,取均值
                        elif col == "Device Weight" and "-" in val_splitted[0]:
                            weight_range = val_splitted[0].split("-")
                            avg_weight = (float(weight_range[0]) + float(weight_range[1])) / 2
                            values.append(avg_weight)
                        else: # 其他列,直接尝试转换为浮点数
                            values.append(float(val_splitted[0]))
                    except ValueError: # 如果转换失败,保留原值
                        values.append(val)
                else: # 如果分割后不是两部分(例如 "1920 x 1080" 或其他复杂字符串),保留原值
                    values.append(val)
            else: # 如果不含空格,直接尝试转换为浮点数
                try:
                    # 检查并替换逗号为小数点
                    if "," in str(val):
                        val = str(val).replace(",", ".")
                    values.append(float(val))
                except ValueError: # 如果转换失败,保留原值
                    values.append(val)
        df_cleaned[col] = values # 将处理后的值赋给新DataFrame的对应列
    else: # 如果列不是'object'类型,直接复制
        df_cleaned[col] = dataset[col]

# 再次查看清洗后数据集的信息和描述性统计
print("\n--- 清洗后数据集信息 ---")
print(df_cleaned.info())

print("\n--- 清洗后数据集的描述性统计 (include='all') ---")
print(df_cleaned.describe(include="all"))
登录后复制

代码解释:

  • df_cleaned = pd.DataFrame(columns=dataset.columns): 创建一个空的DataFrame,与原始DataFrame具有相同的列名,用于存储清洗后的数据。
  • for col in dataset.columns:: 遍历原始DataFrame的每一列。
  • if dataset[col].dtypes == "object":: 检查当前列是否为object类型。只有object类型的列才需要进行特殊处理。
  • if pd.isna(val):: 检查当前值是否为NaN。NaN代表缺失值,直接保留。
  • elif " " in str(val):: 检查值中是否包含空格。这是判断数值和单位是否分离的常见模式。
    • val_splitted = str(val).split(" "): 按空格分割字符串。
    • if "," in val_splitted[0]: ... .replace(",", "."): 处理欧洲等地区使用逗号作为小数点的习惯,将其替换为英文句号。
    • if len(val_splitted) == 2:: 如果分割后得到两部分(通常是数值和单位)。
      • if col == "SSD Capacity": ...: 针对SSD Capacity列进行特殊处理。这里假设我们希望将所有容量统一到TB单位。如果原始单位是GB,则除以1000。
      • elif col == "Device Weight" and "-" in val_splitted[0]:: 处理像 "2 - 4 kg" 这样的范围值,取其平均值。
      • else: values.append(float(val_splitted[0])): 对于其他列,尝试将数值部分直接转换为浮点数。
    • except ValueError:: 如果float()转换失败,说明该值不是纯数字或无法解析为数字,此时保留其原始字符串形式。
    • else: values.append(val): 如果分割后不是两部分(例如"1920 x 1080"),说明它不是简单的数值+单位结构,保留原值。
  • else: try: ... except ValueError: ...: 对于不含空格的object类型值,也尝试直接转换为浮点数,并处理逗号小数点的可能性。
  • df_cleaned[col] = values: 将处理后的值列表赋给新DataFrame的对应列。
  • else: df_cleaned[col] = dataset[col]: 对于非object类型的列,直接复制到新DataFrame。

清洗后的结果

运行上述代码后,df_cleaned.info()会显示许多列的数据类型已成功转换为float64。此时,df_cleaned.describe(include="all")将能够为这些数值列提供准确的描述性统计信息,包括均值(mean)、标准差(std)、最小值(min)、25%分位数、中位数(50%分位数)、75%分位数和最大值(max)。

例如,根据示例输出,我们可以看到Memory Speed、Screen Size、Max Processor Speed、RAM (System Memory)和SSD Capacity等列现在都有了正确的数值统计量。

Memory Speed Screen Size Backlit Max Processor Speed RAM (System Memory) SSD Capacity
count 888.000 994.000 994.000 950.000 987.000 991.000
mean 3339.874 15.336 0.243 4.293 17.431 0.638
std 626.284 0.923 0.429 0.616 12.235 0.423
min 1066.000 10.000 0.000 1.050 4.000 0.000
25% 3200.000 15.600 0.000 4.200 8.000 0.500
50% 3200.000 15.600 0.000 4.400 16.000 0.512
75% 3200.000 15.600 0.000 4.700 16.000 1.000
max 6400.000 18.400 1.000 5.600 128.000 4.000

注意事项与最佳实践

  1. 数据模式的理解:在进行这种复杂的类型转换之前,务必深入了解数据的具体格式和模式。使用df['column_name'].unique()或df['column_name'].value_counts()可以帮助您发现所有不同的值及其出现的频率,从而更好地设计清洗逻辑。
  2. 错误处理:try-except块是关键。它能确保在遇到无法转换为数值的数据时,程序不会崩溃,而是优雅地处理这些异常情况(例如,保留原始字符串或替换为NaN)。
  3. 单位标准化:对于带有单位的数值,务必将其统一到一致的单位。例如,如果SSD Capacity有GB和TB两种单位,需要决定是全部转换为GB还是TB,并进行相应的乘除操作。
  4. 范围值处理:对于像“2 - 4 kg”这样的范围值,可以根据分析需求选择取平均值、取最小值、取最大值或创建新的列来表示范围。
  5. 非数值型字符串:对于像“High”、“Low”、“1920 x 1080”这类本身不代表数值的字符串,应保留其字符串形式,或者在必要时将其转换为分类编码
  6. 性能考虑:对于非常大的数据集,逐行遍历可能会比较慢。可以考虑使用Pandas的apply()方法结合自定义函数,或者使用正则表达式进行更高效的模式匹配和提取。然而,对于复杂且多变的模式,逐值遍历通常是最可靠的方法。

总结

将Pandas中object类型的数值数据转换为可计算的数值类型是数据预处理中的一个常见且关键的步骤。通过系统性地处理缺失值、分离数值与单位、统一小数点格式、标准化单位以及健壮的错误处理,我们可以成功地将这些混合数据转换为纯数值类型。这不仅解锁了对数据进行描述性统计分析的能力,也为后续更深入的数据建模和机器学习任务奠定了坚实的基础。理解数据模式并灵活运用Python和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号