Pandas 中 nan, extract, round 使用总结

本文作者总结了3个Python数据分析常见问题,包括nan相等性比较、pandas按列extract和正则提取、round四舍五入之谜。为方便演示使用tex排版,文末提供使用数据和pdf下载,有疑问可下载资料学习并私信作者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python与算法社区

已原创 452 篇,干货满满

三步加星标

01

02

03

三步加星标

你好,我是 zhenguo

在今天这篇文章,我将总结 3 个Python 数据分析常见问题,分别是:

  1. nan相等性比较问题

  2. pandas 按列 extract 和正则提取

  3. round 四舍五入之谜

为了演示的方便,我使用 tex 排版,文末提供使用数据和pdf下载。

pdf 第一页:

提出nan相等性比较问题;

使用 extract 正则提取,可以实现更复杂的正则表达式提取,很有用;

round 四舍五入问题:

若你有这方面疑问可以下载pdf和google-play-store数据集数据学习,关注视频号,并私信我备注:round

<think>好的,我现在需要帮用户解决他们遇到的pandas报错问题。首先,我要仔细理解他们提供的代码和错误信息。 用户给出的代码片段有三部分: 1. `m_index = df[pd.to_numeric(df['Bytes'], errors='coerce').isnull() == True].index`:这里可能是在找出'Bytes'列中无法转换为数字的行索引。 2. `df['Bytes'].loc[m_index] = ...`:尝试对这些有问题的行进行转换,比如处理带有单位的字符串,比如将"10 MB"转换为10e6。 3. `df['Bytes'] = pd.to_numeric(df['Bytes'], errors='coerce', downcast='integer')`:最后将整个列转换为数值类型,并尝试向下转换为整数。 出现的错误有两个: - SettingWithCopyWarning:这说明用户可能在操作一个DataFrame的副本而不是视图,导致pandas无法确定修改是否会影响原始数据。 - RuntimeWarning:在转换过程中出现了无效值,可能是转换后的数据中存在无法处理的情况,比如浮点数无法转换为整数。 接下来,我需要分析可能的原因: 首先,SettingWithCopyWarning通常发生在链式赋值时。用户使用`df['Bytes'].loc[m_index]`进行赋值,这可能触发了该警告。因为如果df本身是另一个DataFrame的切片副本,pandas会不确定修改是否反映到原数据。解决方法可以是确保df是原始数据的副本,或者使用`.loc`来明确修改的位置。 其次,RuntimeWarning发生在最后一步的`pd.to_numeric`,特别是当尝试将包含浮点数的数据转换为整数时。例如,如果之前用`10e6`转换后的值是浮点数(比如10000000.0),而`downcast='integer'`会尝试将其转为整数类型,但如果有NaN或其他无效值存在,可能会导致转换错误。 可能的解决步骤: 1. 处理SettingWithCopyWarning: - 确保df不是其他DataFrame的切片。可以在创建df时使用`.copy()`来避免这个问题。 - 使用单一.loc访问器来同时选择行和列,例如`df.loc[m_index, 'Bytes'] = ...`,这样更明确且避免链式索引。 2. 处理RuntimeWarning: - 检查转换后的'Bytes'列是否包含非整数值。例如,使用`apply`转换后的值可能有浮点数,而`downcast='integer'`无法处理,可以尝试去掉`downcast`参数,或者先转换为浮点类型,再处理整数转换。 另外,用户可能在处理数据时,例如将字符串转换为数值时,存在一些无法转换的情况,导致`pd.to_numeric`中出现错误。需要确保在apply步骤中所有处理过的值都能正确转换为数字,或者使用`errors='coerce'`来将无效值转为NaN。 可能的代码调整: 修改链式索引: 原代码中的`df['Bytes'].loc[m_index]`可以改为`df.loc[m_index, 'Bytes']`,这样更符合pandas推荐的方式,减少警告的发生。 处理浮点数到整数的转换: 如果最终需要整数类型,可以在apply阶段就将结果转为整数,或者在最后不使用downcast,而是显式转换类型,比如`astype('Int64')`(pandas的可空整数类型)。 此外,还需要检查是否有其他数据问题,例如转换后的值是否超出了整数范围,或者在apply过程中是否有异常数据未被正确处理。 总结步骤: 1. 使用.loc[m_index, 'Bytes']替代链式索引。 2. 确保df不是视图,使用df = original_df.copy()。 3. 检查转换后的数据是否适合转换为整数,或调整downcast参数。 4. 处理可能的NaN或无效值,确保转换过程无误。 这样应该能解决用户的报错问题。</think>让我们逐步分析并解决你的代码中的问题: 1. **理解代码意图**: - 该代码主要处理'Bytes'列的数据清洗: 1) 找出无法直接转换为数字的行(如含单位的字符串"10 MB") 2) 对异常值进行单位转换(如将MB转换为字节数) 3) 最后统一转换为数值类型 2. **警告原因分析**: - ⚠️`SettingWithCopyWarning`: - 触发原因:对DataFrame副本进行操作(可能是通过`df = original_df[condition]`方式创建的视图) - 风险:修改可能不会反映到原始数据中 - 解决方案:使用`.copy()`创建独立副本 ```python df = original_df.copy() # 在数据预处理阶段添加 ``` - ⚠️`RuntimeWarning`: - 触发原因:浮点数强制转换为整数时出现精度损失(如10000000.5转为整数) - 根源:`apply(lambda x: 10e6 * ...)`会产生浮点数,但`downcast='integer'`要求整型 3. **改进后的代码方案**: ```python # 步骤1:创建独立副本(如果df是切片产生的) df = df.copy() # 步骤2:定位需要转换的非数值数据 non_numeric_mask = pd.to_numeric(df['Bytes'], errors='coerce').isna() m_index = df[non_numeric_mask].index # 步骤3:使用安全的.loc赋值方式 df.loc[m_index, 'Bytes'] = ( df.loc[m_index, 'Bytes'] .apply(lambda x: 10e6 * float(x.strip().split()[0])) # 示例转换逻辑 ) # 步骤4:转换时处理数值类型(推荐方案) # 方案A:保持浮点类型(推荐) df['Bytes'] = pd.to_numeric(df['Bytes'], errors='coerce') # 方案B:强制转换为整数(需确保无小数) df['Bytes'] = pd.to_numeric( df['Bytes'], errors='coerce', downcast='integer' ).astype('Int64') # 使用pandas可空整数类型 ``` 4. **优化建议**: - 使用正则表达式提取数值更健壮: ```python df.loc[m_index, 'Bytes'] = ( df.loc[m_index, 'Bytes'] .str.extract(r'([\d.]+)')[0] .astype(float) .mul(10e6) ) ``` - 处理不同单位更灵活: ```python def convert_units(x): num, unit = x.strip().split() multiplier = { 'KB': 1e3, 'MB': 1e6, 'GB': 1e9 }.get(unit.upper(), 1) return float(num) * multiplier ``` 5. **完整解决方案**: ```python # 确保操作独立副本 df = df.copy() # 创建单位转换字典 UNIT_CONVERSION = { 'KB': 10**3, 'MB': 10**6, 'GB': 10**9 } # 处理带单位的数据 def convert_bytes(value): try: number, unit = value.strip().split() return float(number) * UNIT_CONVERSION.get(unit.upper(), 1) except: return np.nan # 分步处理 df['Bytes'] = ( df['Bytes'] .astype(str) .apply(lambda x: convert_bytes(x) if any(c.isalpha() for c in x) else x) .pipe(pd.to_numeric, errors='coerce') ) ``` 这种方案可以: ✅ 避免链式索引警告 ✅ 自动处理多种单位 ✅ 保留数值精度 ✅ 正确处理异常值 如果仍需存储为整数,建议最后添加: ```python df['Bytes'] = df['Bytes'].round().astype('Int64') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值