连接两个带有None值的系列(pandas DataFrame)?
连接两个带有None值的系列(pandas DataFrame)?
我正在尝试在pandas DataFrame中连接两列。问题是,如果任一系列中存在None值,结果将为NaN。
由于真实数据非常大,并且需要保留原始None值以供以后参考,我希望不要更改列中的原始值。在pandas中有没有实现这个的方法?
创建一个示例DataFrame:
import pandas as pd f = pd.DataFrame([['a', 'b','c','a', 'b','c'],['1', '2','3', '4', '5','6', ]]) f = f.transpose() f.columns = ['xx', 'yy'] f.xx[0] = None f.yy[0] = None f.xx[2] = None f.yy[3] = None xx yy 0 None None 1 b 2 2 None 3 3 a None 4 b 5 5 c 6
我尝试了f['new_str'] = f.xx + f.yy
和f['new_str'] = f['xx'] + f['yy']
。如果任何值为None类型,两者都会将连接的值设置为NaN。我认为这是由于pandas如何处理None类型引起的。None类型和str类型不能通过'+'运算符进行相加。
xx yy new_str 0 None None NaN 1 b 2 b2 2 None 3 NaN 3 a None NaN 4 b 5 b5 5 c 6 c6
这是我想要做的:
f['new_str'] = f.xx.map(lambda x: '') for idx, arow in f.iterrows(): con = '' if arow.xx: con += arow.xx if arow.yy: con += arow.yy f.loc[idx,'new_str'] = con f xx yy new_str 0 None None 1 b 2 b2 2 None 3 3 3 a None a 4 b 5 b5 5 c 6 c6
我的问题是,pandas是否支持更简洁/简单的方法来实现这一点?
问题:如何将两个带有None值的Series连接到一个pandas DataFrame中?
解决方法:对每一列调用fillna函数,将None值设置为'',即字符串连接的身份元素。
具体代码如下:
f['new_str'] = f.xx.fillna('') + f.yy.fillna('')
这样就得到了一个按照期望格式的新列。
另一种方法是使用lambda表达式:
f.apply(lambda row: (row['xx'] or '') + (row['yy'] or ''), axis=1)
以上两种方法都不会改变原始列的值,因为左侧没有进行赋值操作。fillna函数在数据的副本上进行操作。
测试结果表明,Liam Foley的解决方法在我的机器上比较快,而且不会创建大型的中间对象,因此内存使用效率也更好。
关于(row['xx'] or '') + (row['yy'] or '')这个技巧,它被称为三元运算符,它选择第一个真值(Truthy)的值,有时也被称为合并运算符。
更多关于三元运算符的信息可以参考这个链接:[stackoverflow.com/questions/394809](http://stackoverflow.com/questions/394809)
还可以参考这个链接了解如何在pandas中使用apply函数处理多个列:[stackoverflow.com/questions/16353729](http://stackoverflow.com/questions/16353729)
通过查看这些链接,我理解了这个简化的写法。(row['xx'] or '')可以简写为(row['xx'] if row['xx'] or ''),这是在条件测试和一个值相同时的一种简写形式。
这个解决方法非常好用!感谢Liam Foley的帮助!