调用Stat_test_wrap函数触发TypeError: object of type 'float' has no len()错误的排查与解决求助
调用Stat_test_wrap函数触发TypeError: object of type 'float' has no len()错误的排查与解决
看起来你遇到的问题根源很清晰,咱们一步步拆解分析:
错误原因
问题出在Stat_test函数的这行代码:
if len(thres) == 2:
当你从Stat_test_wrap里调用Stat_test时,大部分场景传的是单个浮点数(比如Thres[0]是3.7,或者data[Tsel].median()返回的中位数),而单个float类型是没有len()属性的,所以直接调用len(thres)就触发了TypeError。
你看你的Stat_test_wrap调用:
pct20 = Stat_test(data, Tsel, Thres[0])—— 传单个floatMed = Stat_test(data, Tsel, data[Tsel].median())—— 传单个float
只有pct20_80和TharaL_H传的是长度为2的列表,这时候len(thres)才有效。
解决方案
这里给你两种可行的修复思路,按需选择:
思路1:让Stat_test兼容单个数值和列表参数(推荐)
修改Stat_test函数,先判断传入的thres是单个数值还是列表,再执行对应的逻辑:
def Stat_test(data, Tsel, thres): pvalues = [] # 先处理单阈值情况:判断是否是单个数值 if isinstance(thres, (int, float)): data['cat'] = (data[Tsel] >= thres) # 处理双阈值列表情况 elif len(thres) == 2: data['cat'] = (data[Tsel] >= thres[0]) & (data[Tsel] <= thres[1]) else: # 可选:添加异常提示,避免传入无效参数 raise ValueError("thres参数只能是单个整数/浮点数,或者长度为2的列表/元组") data['cat'] = data['cat'].astype('category') # 下面的统计测试代码完全保留原样即可 # sleep quality con1 = pd.crosstab(data['Sleep'], data['cat']) _, m = fisher_exact(con1) pvalues.append(m) _, m1 = wilcoxon(data['Sleep Count'], data['cat'], alternative='two-sided') pvalues.append(m1) _, m1 = wilcoxon(data['hf Sleep Score'], data['cat'], alternative='two-sided') pvalues.append(m1) # ... 后续所有统计代码都保持不变 return pvalues
思路2:修改Stat_test_wrap的调用,统一传列表参数
把所有单个浮点数都包装成长度为1的列表,然后修改Stat_test的判断逻辑:
首先修改Stat_test_wrap:
def Stat_test_wrap(data, Tsel, Thres): # 把单个float包装成列表 pct20 = Stat_test(data, Tsel, [Thres[0]]) pct80 = Stat_test(data, Tsel, [Thres[1]]) TharaL = Stat_test(data, Tsel, [Thres[2]]) TharaH = Stat_test(data, Tsel, [Thres[3]]) Med = Stat_test(data, Tsel, [data[Tsel].median()]) pct20_80 = Stat_test(data, Tsel, Thres[:2]) TharaL_H = Stat_test(data, Tsel, Thres[2:4]) # 后续代码保持不变...
然后修改Stat_test的判断部分:
def Stat_test(data, Tsel, thres): pvalues = [] if len(thres) == 2: data['cat'] = (data[Tsel] >= thres[0]) & (data[Tsel] <= thres[1]) elif len(thres) == 1: data['cat'] = (data[Tsel] >= thres[0]) else: raise ValueError("thres必须是长度为1或2的列表/元组") # 后续代码保持不变...
额外小提示
注意哦,你在Stat_test里直接修改了传入的data数据框(添加了cat列),如果多次调用这个函数,可能会覆盖之前的cat值或者重复添加列。建议在函数内部先复制一份数据,比如:
data_copy = data.copy() # 之后所有操作都用data_copy代替data data_copy['cat'] = ...
这样就不会污染你的原始数据啦。
备注:内容来源于stack exchange,提问作者Rai
相关产品推荐
相关产品推荐

