将英尺英寸格式的身高Series转换为厘米时遇AttributeError问题求助
解决Pandas中英尺英寸转厘米的AttributeError问题
问题场景
需要将Pandas Series中存储为英尺英寸格式(如5' 11")的身高数据转换为厘米数值,执行自定义转换函数时触发AttributeError。
数据样例
调用fighter_details.Height.head()返回结果:
INDEX Data 0 NaN 1 5' 11" 2 6' 3" 3 5' 11" 4 5' 6"
自定义转换函数
import numpy as np import pandas as pd def inch_to_cm(x): if x is np.NaN: return x else: # format: '7\' 11"' ht_ = x.split("' ") ft_ = float(ht_[0]) in_ = float(ht_[1].replace('"',"")) return ((12*ft_) + in_) * 2.54
执行代码与报错
执行代码:
fighter_details['Height'] = fighter_details['Height'].apply(inch_to_cm)
报错信息:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [240], in <cell line: 1>() ----> 1 fighter_details['Height'] = fighter_details['Height'].apply(inch_to_cm) File ~/opt/anaconda3/envs/book_env/lib/python3.8/site-packages/pandas/core/series.py:4108, in Series.apply(self, func, convert_dtype, args, **kwds) 4106 else: 4107 values = self.astype(object)._values -> 4108 mapped = lib.map_infer(values, f, convert=convert_dtype) 4110 if len(mapped) and isinstance(mapped[0], Series): 4111 # GH 25959 use pd.array instead of tolist 4112 # so extension arrays can be used 4113 return self._constructor_expanddim(pd_array(mapped), index=self.index) File pandas/_libs/lib.pyx:2467, in pandas._libs.lib.map_infer() Input In [239], in inch_to_cm(x) 3 return x 4 else: 5 # format: '7\' 11"' ----> 6 ht_ = x.split("' ") 7 ft_ = float(ht_[0]) 8 in_ = float(ht_[1].replace('"',"")) AttributeError: 'float' object has no attribute 'split'
错误原因
x is np.NaN无法正确识别Pandas中的缺失值:
- Pandas里的NaN是
float类型的np.nan,但用is判断时,由于内存地址等问题,无法匹配所有NaN实例 - 导致NaN值进入else分支,而NaN是float类型,没有
split方法,触发AttributeError
解决方法
方法1:修正NaN判断逻辑
使用pd.isna()或np.isnan()替代is判断,确保正确识别缺失值:
def inch_to_cm(x): if pd.isna(x): return x else: ht_ = x.split("' ") ft_ = float(ht_[0]) in_ = float(ht_[1].strip('"')) return ((12 * ft_) + in_) * 2.54
重新执行apply即可:
fighter_details['Height'] = fighter_details['Height'].apply(inch_to_cm)
方法2:用Pandas字符串方法高效处理(推荐)
避免apply循环,用str.extract直接提取英尺和英寸数值,计算更高效:
# 提取英尺和英寸,生成两列数值 height_extract = fighter_details['Height'].str.extract(r'(\d+)\' (\d+)"').astype(float) # 计算厘米:(英尺*12 + 英寸)*2.54 fighter_details['Height'] = (height_extract[0]*12 + height_extract[1])*2.54
这种方法自动忽略NaN值,无需额外判断,性能更优。
内容的提问来源于stack exchange,提问作者epg32
相关产品推荐
相关产品推荐

