将(lambda)函数映射到字符串列表时出错:“float”对象不可迭代
我在试图弄清楚我的Python脚本哪里出错。我有一个pandas的Series(diagnoses
),里面是一些列表,每个列表里都是字符串(绝对不会是空的)。我已经用diagnoses.map(type)
确认过这一点。
for x in diagnoses[0]:
type x
但是,当我想对这个包含列表的Series使用一个lambda函数时,却出现了TypeError: 'float' object not iterable
的错误。
想象一下,数据大概是这样的:
LopNr AR var3 va4 var5 var6 var7 var8 var9 var10 DIAGNOS
6 2011 S834
6 2011 K21 S834
而我的代码是:
from pandas import *
tobacco = lambda lst: any( (((x >= 'C30') and (x<'C40')) or ((x >= 'F17') and (x<'F18'))) for x in lst)
treatments = read_table(filename,usecols=[0,1,10])
diagnoses = treatments['DIAGNOS'].str.split(' ')
treatments['tobacco'] = diagnoses.map(tobacco)
到底发生了什么,我该怎么解决这个问题呢?
附注:同样的代码在另一个非常相似的Series上运行得很好,只要我先用IOpro
导入源文本文件,然后从那个适配器构建一个数据框。下面有相关内容。我不明白为什么这样会改变相关的数据类型,因为我确认过在这两种情况下,pandas的Series里都是字符串的列表……我使用的是Python 2.7.6和pandas 0.13.1。
import iopro
adapter = iopro.text_adapter(filename,parser='csv',field_names=True,output='dataframe',delimiter='\t')
treatments = adapter[['LopNr','AR','DIAGNOS']][:]
1 个回答
3
出现 TypeError: 'float' object is not iterable
这个错误,可能是因为数据中缺少了 DIAGNOS
的值。例如,当数据看起来像这样:
LopNr AR var3 va4 var5 var6 var7 var8 var9 var10 DIAGNOS
6 2011 a a a a a a a a S834
6 2011 a a a a a a a a
6 2011 a a a a a a a a K21 S834
那么
In [68]: treatments = pd.read_table('data', usecols=[0,1,10])
In [69]: treatments
Out[69]:
LopNr AR DIAGNOS
0 6 2011 S834
1 6 2011 NaN
2 6 2011 K21 S834
[3 rows x 3 columns]
在 DIAGNOS
列中的 NaN
就是问题的根源,因为 str.split(' ')
会保留这个 NaN:
In [70]: diagnoses = treatments['DIAGNOS'].str.split(' ')
In [71]: diagnoses
Out[72]:
0 [S834]
1 NaN
2 [K21, S834]
Name: DIAGNOS, dtype: object
当调用 diganose.map(tobacco)
时,NaN
会被传递给 tobacco
函数。由于 NaN
是一个浮点数,而不是可迭代的对象,所以在 for x in lst
的循环中就会引发 TypeError
。
为了避免这个错误,可以替换掉 treatments['DIAGNOS']
中的 NaN:
import pandas as pd
def tobacco(lst):
return any((('C30' <= x < 'C40') or ('F17' <= x <'F18')) for x in lst)
treatments = pd.read_table('data', usecols=[0,1,10])
treatments['DIAGNOS'].fillna('', inplace=True)
diagnoses = treatments['DIAGNOS'].str.split(' ')
treatments['tobacco'] = diagnoses.map(tobacco)
print(treatments)
结果是
LopNr AR DIAGNOS tobacco
0 6 2011 S834 False
1 6 2011 False
2 6 2011 K21 S834 False
[3 rows x 4 columns]