python中nan、字符串 ‘nan‘ 、浮点数 float(‘nan‘) 不同,使用常规替换方式无法转换为None

背景:

用python读取excel中的数据,生成insert into sql。发现打印出来的sql中存在nan。使用

df = df.where(pd.notna(df), None) 对DF转换,以及[None if item == 'nan' else item for item in ordered_values] 对遍历出的列表进行转换均无法转换。

核心代码:

# 将 NaN 值替换为 None
df = df.where(pd.notna(df), None)

df = df.applymap(lambda x: x if pd.notna(x) else None)


ordered_values_new = [None if item == 'nan' else item for item in ordered_values]

发现处理后仍有nan。

打印数据类型

for item in ordered_values_new:
    print(f'Item: {item}, Type: {type(item)}')


##打印结果
Item: nan, Type: float

发现数据类型为 float,无法转换

解决方式1:

我们可以使用 try-except 块来安全地尝试将元素转换为浮点数,并在转换失败时保留原始值。

import math

ordered_values = ['1', '2', 'nan', '4', float('nan'), 'hello', 5]

# 使用 try-except 块来安全地尝试将元素转换为浮点数
ordered_values_new = []
for item in ordered_values:
    try:
        # 尝试将元素转换为浮点数并检查是否为 NaN
        if math.isnan(float(item)):
            ordered_values_new.append(None)
        else:
            ordered_values_new.append(item)
    except ValueError:
        # 如果转换失败,保留原始值
        ordered_values_new.append(item)

for item in ordered_values_new:
    print(f'Item: {item}, Type: {type(item)}')

在这个方案中,我们使用 try-except 块来尝试将每个元素转换为浮点数。如果转换成功并且结果是 NaN,则将其替换为 None。如果转换失败(例如,对于非数字字符串或非浮点数的其他类型),则保留原始值。

解决方式2:

import pandas as pd

ordered_values = ['1', '2', 'nan', '4', float('nan'), 'hello', 5, None, pd.NA]

# 使用 pd.isna() 来检测多种形式的缺失值
ordered_values_new = [None if pd.isna(item) else item for item in ordered_values]

for item in ordered_values_new:
    print(f'Item: {item}, Type: {type(item)}')

在这个方案中,pd.isna() 函数会检测多种形式的缺失值,包括 NaNNone 以及 pd.NA,并将它们替换为 None。这种方式更为通用和温和,因为它不需要显式地进行类型转换,也不会抛出异常。

解决方式3:

我们可以编写一个函数来检测多种形式的缺失值,包括 NaNNone 以及字符串 'nan'

import math

def is_missing(value):
    if value is None:
        return True
    elif isinstance(value, str) and value.lower() == 'nan':
        return True
    elif isinstance(value, float) and math.isnan(value):
        return True
    return False

ordered_values = ['1', '2', 'nan', '4', float('nan'), 'hello', 5, None]

# 使用自定义的 is_missing 函数来检测多种形式的缺失值
ordered_values_new = [None if is_missing(item) else item for item in ordered_values]

for item in ordered_values_new:
    print(f'Item: {item}, Type: {type(item)}')

我们定义了一个 is_missing 函数,用于检测多种形式的缺失值。该函数会检查以下几种情况:

  1. 值是否为 None

  2. 值是否为字符串 'nan'(不区分大小写)。

  3. 值是否为浮点数 NaN

然后,我们使用这个函数在列表推导式中检测并替换缺失值。

备注:只做临时记录,另外的文章展示完整的代码:python读取excel,转换为JSON/INSERT SQL语句-CSDN博客

以下是针对这个问题的代码实现及解释。 ```python import pandas as pd # 读取数据文件 df = pd.read_csv('file.csv', header=None) # 删除值全为 Nan 的行,删除序号列 df = df.dropna(how='all').iloc[:, 1:] # 对 df 对象进行列索引标识 columns = ['姓名', '年龄', '体重', '男性胸围', '男性腰围', '男性臀围', '女性胸围', '女性腰围', '女性臀围'] df.columns = columns # 年龄Nan 值用年龄的均值替换 df['年龄'] = df['年龄'].fillna(df['年龄'].mean()) # 将体重列单位为 kgs 的数据全部变换成单位为 lbs 的数据(1kgs=2.21bs),再去除1bs后缀 df['体重'] = df['体重'].apply(lambda x: x.replace('kgs', '') if isinstance(x, str) else x) df['体重'] = df['体重'].apply(lambda x: float(x)*2.2046 if isinstance(x, str) else x) df['体重'] = df['体重'].apply(lambda x: str(int(x)) if isinstance(x, float) else x) # 将体重列 Nan 值用体重的均值替换 df['体重'] = df['体重'].apply(lambda x: float(x) if isinstance(x, str) else x) df['体重'] = df['体重'].fillna(df['体重'].mean()) df['体重'] = df['体重'].apply(lambda x: str(int(x)) if isinstance(x, float) else x) # 剔除会员姓名列的异常字符,再将会员的姓名划分为姓和名两列 df['姓名'] = df['姓名'].apply(lambda x: ''.join(filter(str.isalpha, x))) df['姓'] = df['姓名'].apply(lambda x: x[0]) df['名'] = df['姓名'].apply(lambda x: x[1:]) # 将女性会员的腰围列nan 用女性腰围的均值替换 avg_female_waist = df['女性腰围'].mean() df['女性腰围'] = df['女性腰围'].fillna(avg_female_waist) # 在 df 对象增加一个性别列,男性值为"1",女性值为"0" df['性别'] = df.apply(lambda x: 1 if x['男性胸围'] else 0, axis=1) # 打印处理后的 DataFrame 对象 print(df) ``` 代码实现的具体解释如下: - 第1行:导入 pandas 库。 - 第3行:使用 pandas 库的 `read_csv()` 函数读取数据文件,`header=None` 参数表示数据文件没有列名,因此需要手动添加列名。 - 第6行:使用 pandas 库的 `dropna()` 函数删除值全为 Nan 的行,`iloc[:, 1:]` 表示删除序号列。 - 第9行:使用 `columns` 列表存储数据文件的列名,并使用 `columns` 列表为 DataFrame 对象添加列索引标识。 - 第12行:使用 DataFrame 对象的 `fillna()` 函数将年龄Nan 值用年龄的均值替换。 - 第16行:使用 DataFrame 对象的 `apply()` 函数和 `lambda` 表达式将体重列单位为 kgs 的数据全部变换成单位为 lbs 的数据(1kgs=2.21bs),再去除1bs后缀。 - 第21行:使用 DataFrame 对象的 `fillna()` 函数将体重列 Nan 值用体重的均值替换。 - 第22行:使用 DataFrame 对象的 `apply()` 函数和 `lambda` 表达式将体重列浮点数转换为整型,并转换字符串类型。 - 第27行:使用 DataFrame 对象的 `apply()` 函数和 `lambda` 表达式剔除会员姓名列的异常字符,只保留姓名的字母。 - 第28行:使用 DataFrame 对象的 `apply()` 函数和 `lambda` 表达式将会员的姓名划分为姓和名两列。 - 第31行:使用 DataFrame 对象的 `mean()` 函数计算女性腰围的均值,并将其存储在 `avg_female_waist` 变量。 - 第32行:使用 DataFrame 对象的 `fillna()` 函数将女性会员的腰围列nan 用女性腰围的均值替换。 - 第35行:使用 DataFrame 对象的 `apply()` 函数和 `lambda` 表达式在 df 对象增加一个性别列,男性值为"1",女性值为"0"。 - 第38行:使用 `print()` 函数打印处理后的 DataFrame 对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值