0

0

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

聖光之護

聖光之護

发布时间:2025-11-21 14:50:20

|

397人浏览过

|

来源于php中文网

原创

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等信息,而不会计算均值、标准差等数值统计量。

Napkin AI
Napkin AI

Napkin 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的数据处理功能,是成为高效数据分析师的关键技能。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

531

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

258

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

766

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

219

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

357

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

245

2023.11.17

正则表达式中如何匹配数字
正则表达式中如何匹配数字

正则表达式中可以通过匹配单个数字、匹配多个数字、匹配固定长度的数字、匹配整数和小数、匹配负数和匹配科学计数法表示的数字的方法匹配数字。更多关于正则表达式的相关知识详情请看本专题下面的文章。php中文网欢迎大家前来学习。

548

2023.12.06

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 21.4万人学习

成为PHP架构师-自制PHP框架
成为PHP架构师-自制PHP框架

共28课时 | 2.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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