将R中apply函数转换为Python时遇prob列NaN问题求助
问题分析与解决方案
你的Python代码返回NaN的核心原因是:在apply的lambda函数中,你使用x[0]来获取当前行的total值,但x是一个Series,其索引是列名'total'而非整数索引,x[0]会尝试查找索引标签为0的元素,导致KeyError,最终apply返回NaN。
修正后的代码
import numpy as np import pandas as pd var = 0.08 a = pd.DataFrame(np.random.uniform(0, 1, size=(10, 4)), columns=['a', 'b', 'c', 'd']) b = pd.DataFrame({'a': [0,4,6,8,10,12,12,14,16,18], 'b': [2,6,8,10,12,14,14,16,18,20], 'c': [4,8,10,12,14,16,16,18,20,22], 'd': [6,10,12,14,16,18,18,20,22,24]}) output = pd.DataFrame({'total': range(0, 11)}) # 提取重复的掩码,避免重复计算 mask_even = output['total'] % 2 == 0 mask_odd = output['total'] % 2 == 1 # 使用x['total']按标签取值(推荐,更清晰) output.loc[mask_even, 'prob'] = output[mask_even].apply( lambda x: np.sum(a * (b == x['total'])), axis=1 ) output.loc[mask_odd, 'prob'] = output[mask_odd].apply( lambda x: np.sum(a * (b == (x['total'] - 1))) * var / (1 - var), axis=1 ) print(output)
关键修正点
- 替换
x[0]为x['total']:x是output子DataFrame的一行,是一个Series,其索引为列名'total',因此必须通过标签x['total']获取对应值;也可以用x.iloc[0]按位置取值,但x['total']更具可读性,不易出错。
- 简化索引操作:
- 原代码中的
a.iloc[:, 0:4]和b.iloc[:, 0:4]可直接用a和b代替,因为两者的列数正好是4列,且列名完全匹配,不影响元素级运算。
- 原代码中的
- 提取掩码变量:
- 将重复的条件判断结果存入
mask_even和mask_odd,提升代码可读性和运行效率。
- 将重复的条件判断结果存入
补充说明
这段代码的逻辑和你提供的R代码完全一致:
- 对偶数
total,计算a与b中等于total的元素的乘积之和; - 对奇数
total,计算a与b中等于total-1的元素的乘积之和,再乘以var/(1-var)。
运行修正后的代码,prob列将返回正确的数值而非NaN。
内容的提问来源于stack exchange,提问作者petebish07
相关产品推荐
相关产品推荐

