You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas处理含np.float32值的字典列去重时,如何避免转字符串出现np.float32标识?

Pandas处理含np.float32值的字典列去重时,如何避免转字符串出现np.float32标识?

这个问题我之前也踩过坑!核心问题有两个:一是字典属于不可哈希类型,直接用drop_duplicates会报错;二是转字符串时,numpy的np.float32实例会被序列化成np.float32(123.02)这种格式,导致ast.literal_eval解析失败。

给你几个不用事后替换的优雅解决方案:

方案1:先把字典里的numpy类型转成原生Python数值

在把字典转字符串之前,先把字典里的np.float32(或其他numpy数值类型)转换成Python原生的float,这样转字符串时就只会显示纯数值了:

import numpy as np
import pandas as pd
import ast

# 定义转换函数:把字典里的numpy数值转成原生Python类型
def convert_numpy_to_python(d):
    converted = {}
    for k, v in d.items():
        if isinstance(v, np.floating):  # 处理所有numpy浮点类型
            converted[k] = float(v)
        elif isinstance(v, np.integer):  # 可选:处理numpy整数类型
            converted[k] = int(v)
        else:
            converted[k] = v
    return converted

# 对所有字典列应用转换函数
df['foo'] = df['foo'].apply(convert_numpy_to_python)
df['bar'] = df['bar'].apply(convert_numpy_to_python)

# 现在再用你原来的转字符串去重方法就不会有问题了
df = df.map(str).T.drop_duplicates().T
# 解析回字典也能正常工作
df['foo'] = df['foo'].apply(ast.literal_eval)
df['bar'] = df['bar'].apply(ast.literal_eval)

方案2:不用转字符串,直接生成可哈希的标识去重

其实我们可以绕开字符串转换的环节,把字典转换成可哈希的结构(比如排序后的键值对元组),用这个来判断行是否重复,效率会更高:

import pandas as pd
import numpy as np

# 生成每一行的可哈希唯一标识
def get_row_identifier(row):
    # 把字典转成排序后的键值对元组(保证键顺序不影响重复判断)
    foo_id = tuple(sorted(row['foo'].items()))
    bar_id = tuple(sorted(row['bar'].items()))
    return (foo_id, bar_id)

# 新增一个临时列存储可哈希标识
df['row_id'] = df.apply(get_row_identifier, axis=1)

# 基于临时列去重,然后删掉临时列
df = df.drop_duplicates(subset='row_id').drop(columns='row_id')

这个方法的好处是不需要来回转换字符串和字典,避免了类型解析的风险,而且判断重复的逻辑更直接——只要两个行的foo和bar字典内容完全一致(键值对相同,顺序不影响),就会被判定为重复。

为什么原来的方法会出问题?

当你用df.map(str)时,numpy的数值类型(比如np.float32)会调用它自己的__repr__方法,输出带有类型标识的字符串。提前把这些numpy类型转成Python原生的float,转字符串时就会输出纯数值格式,ast.literal_eval就能正常解析了。

备注:内容来源于stack exchange,提问作者pip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 09:09:51