熊猫系列应用lambda:未找到类型,但系列中只有str和list

时间:2019-06-25 10:03:31

标签: python python-3.x pandas dataframe lambda

编辑:jezrael对于我在下面提出的问题有正确的答案。不幸的是,我问错了问题。事实证明,问题在于DataFrame列中的字符串列表包含None元素,这就是错误的出处。请查看我为解决此问题而添加的代码的答案。

第二编辑:jezrael更新了他的回答,以一种做我所做的方式,但更简洁地使用了lambda表达式。


我有一个DataFrame,我在其中选择一个列,在其上调用apply,在该列上提供lambda表达式的参数,该表达式是if语句。我知道在这一点上该列被视为一个系列。

该列由字符串和字符串列表组成,我希望通过连接字符串的元素并将其列表替换为结果字符串,将后者转换为纯字符串,以便FataFrame列就是字符串。

相关代码:

raw_data.address = raw_data.address.fillna('')

这时,我遍历了整个address列,并将所有类型添加到集合中-该集合中仅有的元素是strlist

raw_data.address.apply(lambda x: x if type(x) == str else ' '.join(x))

raw_data.address.apply(lambda x: x if isinstance(x, str) else ' '.join(x))

不起作用。

这是两种情况下的错误消息:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-32-5e2dce775d20> in <module>
----> 1 raw_data.address.apply(lambda x: x if type(x) == str else ' '.join(x))

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args, **kwds)
   3589             else:
   3590                 values = self.astype(object).values
-> 3591                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   3592 
   3593         if len(mapped) and isinstance(mapped[0], Series):

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-32-5e2dce775d20> in <lambda>(x)
----> 1 raw_data.address.apply(lambda x: x if type(x) == str else ' '.join(x))

TypeError: sequence item 0: expected str instance, NoneType found

我不明白为什么这行不通。我的理解是语法正确。

2 个答案:

答案 0 :(得分:2)

比较列表并删除None值:

raw_data = pd.DataFrame({'address':[['a', 'b', None], 'c']})
print (raw_data)
        address
0  [a, b, None]
1             c

raw_data.address = (raw_data.address
                            .apply(lambda x: ' '.join(filter(None, x)) 
                                             if isinstance(x, list)
                                             else x))
print (raw_data)
  address
0     a b
1       c

答案 1 :(得分:0)

事实证明,问题在于DataFrame中的列表本身包含None个元素。为了解决这个问题,我没有编写apply使用lambda函数,而是编写了一个普通函数,该函数使用内置函数filter删除了列表中的None

def make_strings(thing):
    if isinstance(thing, list):
        return ' '.join(filter(None, thing))
    else:
        return str(thing)