LeetCode刷题时fillna(0)无法将空值转为0,求问题原因
问题分析:fillna(0)未生效的原因及修复方案
你遇到的fillna(0)无法转换空值的核心原因是:当某商品无销售记录(units为NaN)时,groupby求和后sum_product与units均为0,计算sum_product / units得到的是NaN(0除以0的结果),虽然最后调用了fillna(0),但中间逻辑的空值传递导致最终空值未被正确覆盖。
具体代码问题拆解
以测试用例中product_id=3为例:
- 外连接后,product_id=3的
units为NaN,purchase_date为NaN,符合筛选条件被保留; calculated_df中units * price得到NaN(NaN*30=NaN);- groupby求和时,NaN会被忽略,因此
sum_product和units的总和均为0; - 计算
average_price时,0/0得到NaN,此时fillna(0)理论上可转换该NaN,但因中间步骤的空值传递,导致最终空值未被正确识别处理。
修复方案
以下几种方式可以彻底解决问题:
方案1:提前填充销售数量的空值
在计算sum_product前,将units的NaN填充为0,避免中间产生无效的NaN:
import pandas as pd def average_selling_price(prices: pd.DataFrame, units_sold: pd.DataFrame) -> pd.DataFrame: merged_df = units_sold.merge(prices, on='product_id', how='outer') filtered_df = merged_df[((merged_df['purchase_date'] >= merged_df['start_date']) & (merged_df['purchase_date'] <= merged_df['end_date'])) | merged_df['purchase_date'].isnull()] calculated_df = filtered_df.copy(deep=True)[['product_id', 'units', 'price']] # 提前填充units的空值为0 calculated_df['units'] = calculated_df['units'].fillna(0) calculated_df['sum_product'] = calculated_df['units'] * calculated_df['price'] pivoted_df = calculated_df.groupby('product_id').agg({'sum_product': 'sum', 'units': 'sum'}).reset_index() # 处理除以0的情况,直接赋值为0 pivoted_df['average_price'] = round(pivoted_df['sum_product'] / pivoted_df['units'], 2).fillna(0) pivoted_df = pivoted_df[['product_id', 'average_price']] return pivoted_df
方案2:用numpy处理除以0的场景
使用np.divide的where参数,直接避免0/0的情况:
import pandas as pd import numpy as np def average_selling_price(prices: pd.DataFrame, units_sold: pd.DataFrame) -> pd.DataFrame: merged_df = units_sold.merge(prices, on='product_id', how='outer') filtered_df = merged_df[((merged_df['purchase_date'] >= merged_df['start_date']) & (merged_df['purchase_date'] <= merged_df['end_date'])) | merged_df['purchase_date'].isnull()] calculated_df = filtered_df.copy(deep=True)[['product_id', 'units', 'price']] calculated_df['sum_product'] = calculated_df['units'] * calculated_df['price'] pivoted_df = calculated_df.groupby('product_id').agg({'sum_product': 'sum', 'units': 'sum'}).reset_index() # 使用numpy处理除以0,直接返回0 pivoted_df['average_price'] = round(np.divide(pivoted_df['sum_product'], pivoted_df['units'], out=np.zeros_like(pivoted_df['sum_product']), where=pivoted_df['units'] != 0), 2) pivoted_df = pivoted_df[['product_id', 'average_price']] return pivoted_df
方案3:调整fillna的时机
在计算average_price后立即填充空值,确保所有NaN都被覆盖:
# 替换原代码中计算average_price的行 pivoted_df['average_price'] = round(pivoted_df['sum_product'] / pivoted_df['units'], 2).fillna(0)
验证测试
用你的最小复现示例测试,修复后的代码会正确返回product_id=3的average_price为0,符合预期。
内容的提问来源于stack exchange,提问作者wanyingq
相关产品推荐
相关产品推荐

