
Pandas DataFrame中,包含数值信息但被识别为对象(object)类型的列,在进行描述性统计分析时会遇到障碍。本文将详细介绍一种实用的数据清洗方法,通过迭代处理这些列中的字符串值,识别并提取数值部分,统一单位,并将其转换为适当的数值类型,最终实现对这些转换后数值列的均值、标准差等统计量的准确计算。
在数据分析的初期阶段,描述性统计是理解数据集特征的关键步骤。然而,当数据集中的数值信息被存储为字符串(即Pandas中的object类型)时,直接计算均值、中位数或标准差等统计量会变得困难或不可能。这通常发生在数据导入时,由于数值中包含单位(如“15.6 inches”、“3.4 GHz”、“4 GB”)、非标准的小数分隔符(如逗号代替点)或混合了非数值字符(如“1920 x 1080”),Pandas无法自动将其识别为数值类型。
本教程将引导您完成一个实际案例,演示如何通过逐列逐值检查和转换,将这些“假性数值”的object类型列清洗为真正的数值类型,从而能够进行准确的描述性统计分析。
1. 数据加载与初步观察
首先,我们需要加载数据并检查其初始状态。我们将使用pandas.read_excel读取.xlsx文件,并通过df.info()和df.head()来初步了解数据的结构和类型。
import pandas as pdimport numpy as np# 假设您的数据文件名为 'data.xlsx' 或 'Dataset.xlsx'try: df = pd.read_excel('data.xlsx')except FileNotFoundError: df = pd.read_excel('Dataset.xlsx')print("--- 原始数据信息 (df.info()) ---")df.info()print("n--- 原始数据前5行 (df.head()) ---")print(df.head())print("n--- 原始数据描述性统计 (df.describe(include='all')) ---")print(df.describe(include='all'))
从df.info()的输出中,您会发现许多本应是数值的列(例如“Memory Speed”、“Screen Size”、“Max Processor Speed”、“RAM (System Memory)”、“SSD Capacity”等)被识别为object类型。直接对这些object列调用df.describe()(即使include=’all’),也只会显示计数、唯一值、众数等针对分类数据的统计信息,而无法提供均值、标准差等数值统计量。
2. 核心策略:逐列逐值清洗与转换
为了计算这些“假性数值”列的统计量,我们必须手动将其转换为数值类型。这个过程涉及遍历DataFrame的每一列,特别是object类型的列,然后对每个单元格的值进行检查、清洗和类型转换。
我们将创建一个新的DataFrame df_new 来存储转换后的数据,以避免修改原始DataFrame。
# 创建一个空的DataFrame,用于存储清洗和转换后的数据df_new = pd.DataFrame(columns=df.columns)# 遍历原始DataFrame的每一列for col in df.columns: # 检查当前列的数据类型是否为 'object' if df[col].dtypes == "object": values = [] # 初始化一个空列表,用于存储当前列转换后的值 # 遍历当前列中的每一个值 for val in df[col].values: if pd.isna(val): # 如果值是NaN(缺失值),则直接添加NaN values.append(np.nan) elif isinstance(val, (int, float)): # 如果值已经是数值类型(可能在某些情况下混入),直接添加 values.append(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: # 尝试将第一部分转换为浮点数 numeric_val = float(val_splitted[0]) # 特殊处理 'SSD Capacity' 列的单位统一 if col == "SSD Capacity": if val_splitted[1].lower() == "gb": # 将GB转换为TB,方便后续统一计算 values.append(numeric_val / 1000) elif val_splitted[1].lower() == "tb": # TB单位直接使用 values.append(numeric_val) else: # 其他未知单位,保留原始字符串 values.append(val) else: # 其他列直接添加转换后的数值 values.append(numeric_val) except ValueError: # 如果无法转换为浮点数(例如,单位不是数字) values.append(val) # 保留原始字符串 else: # 如果分割后不是两部分(例如“1920 x 1080”),保留原始字符串 values.append(val) else: # 如果字符串中没有空格,尝试直接转换为浮点数 try: # 处理小数点分隔符:将逗号替换为点 processed_val = str(val).replace(",", ".") values.append(float(processed_val)) except ValueError: # 如果无法转换,保留原始字符串 values.append(val) # 将处理后的值列表赋值给df_new的对应列 df_new[col] = values else: # 如果列不是 'object' 类型(例如 'int64'),直接复制到df_new df_new[col] = df[col]print("n--- 转换后数据信息 (df_new.info()) ---")df_new.info()
代码解析:
初始化 df_new: 创建一个与原始DataFrame列名相同的空DataFrame。遍历列: 对原始DataFrame中的每一列进行迭代。判断 object 类型: 只有object类型的列才需要进行清洗和转换。非object类型的列(如int64)直接复制到df_new。处理缺失值: pd.isna(val) 用于识别并保留 NaN 值。处理带单位的字符串:if ” ” in str(val): 检查值中是否包含空格。如果包含,则假定它是由数值和单位组成的字符串。str(val).split(” “): 使用空格将字符串分割成列表。replace(“,”, “.”): 统一小数点分隔符,将逗号替换为点,以确保float()函数能正确解析。try-except ValueError: 尝试将分割后的第一部分转换为浮点数。这是一个健壮的错误处理机制,如果转换失败(例如,字符串不是有效的数字格式),则将原始值保留,避免程序崩溃。单位统一化 (SSD Capacity): 这是一个关键步骤。例如,如果“SSD Capacity”列包含“256 GB”和“1 TB”,为了计算平均值,需要将它们统一到相同的单位(例如,都转换为TB)。这里我们将GB除以1000转换为TB。处理复杂格式: 对于像“1920 x 1080”这样的多部分字符串,由于它们不代表单个数值,我们选择保留其原始字符串形式。处理纯数值字符串: 如果字符串中没有空格,则直接尝试将其转换为浮点数,同样进行逗号到点的替换和错误处理。赋值: 将处理后的值列表赋值给df_new中对应的列。
3. 结果验证与分析
完成数据清洗和类型转换后,我们可以再次运行df_new.describe(include=”all”)来查看新的描述性统计结果。
print("n--- 转换后数据描述性统计 (df_new.describe(include='all')) ---")print(df_new.describe(include='all'))
您会注意到,现在“Memory Speed”、“Screen Size”、“Max Processor Speed”、“RAM (System Memory)”和“SSD Capacity”等列已经成功转换为数值类型,并且describe()函数能够为它们提供均值(mean)、标准差(std)、最小值(min)、最大值(max)以及四分位数等全面的数值统计信息。这表明我们的数据清洗工作取得了成功。
4. 注意事项与进一步优化
通用性: 上述方法对于结构化但格式不统一的字符串数值非常有效。它通过明确的规则来解析和转换数据。非数值object列: 对于那些本质上就是分类或文本数据的object列(例如“Operating System”、“Product Model”),此方法会保留其字符串形式,describe(include=’all’)仍然会显示其分类统计。单位统一: 在进行数值转换时,单位统一是至关重要的。在处理像“SSD Capacity”这样的列时,务必确保所有数值都转换为相同的基准单位,否则计算出的统计量将毫无意义。错误处理: try-except ValueError 块是确保代码健壮性的关键。它允许程序在遇到无法转换的值时继续执行,而不是崩溃。正则表达: 对于更复杂的字符串模式匹配和提取,可以考虑使用Python的re模块(正则表达式)结合Pandas的str.extract()方法,这可能使代码更简洁,尤其是在处理多种单位和复杂格式时。例如,df[‘Column’].str.extract(‘(d+.?d*)s*(GB|TB|MHz)’).astype(float)。pd.to_numeric: Pandas的pd.to_numeric()函数是一个强大的工具,结合errors=’coerce’参数可以快速将非数值转换为NaN。但它不直接处理单位提取和单位转换,通常需要配合字符串操作(如str.replace或正则表达式)来预处理。
总结
数据预处理是任何数据分析项目的基础,而将object类型中包含的数值信息正确转换为数值类型是其中的一个常见挑战。通过本教程介绍的逐列逐值清洗和转换方法,您可以有效地处理这些复杂情况,解锁对数据集进行更深入、更准确的数值分析的能力。理解数据的原始格式并设计相应的清洗逻辑,是成为一名优秀数据分析师的关键技能之一。
以上就是如何在Pandas中高效处理对象类型列并计算数值统计量的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1381694.html
微信扫一扫
支付宝扫一扫