将(lambda)函数映射到字符串列表时出错:“float”对象不可迭代

0 投票
1 回答
2218 浏览
提问于 2025-04-18 07:32

我在试图弄清楚我的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]

撰写回答