Pandas中的.apply()函数异常处理

44

如果我有一个DataFrame:

myDF = DataFrame(data=[[11,11],[22,'2A'],[33,33]], columns = ['A','B'])

给出以下数据框(在 Stack Overflow 上开始并没有足够的声望来上传数据框的图像)

   | A  | B  |

0  | 11 | 11 |

1  | 22 | 2A |

2  | 33 | 33 |

如果我想将B列转换为整数值并删除无法转换的值,我需要执行以下操作:

def convertToInt(cell):
    try:
        return int(cell)
    except:
        return None
myDF['B'] = myDF['B'].apply(convertToInt)
如果我只执行以下操作:
``` myDF['B'].apply(int) ```
显然会出现以下错误:
``` C:\WinPython-32bit-2.7.5.3\python-2.7.5\lib\site-packages\pandas\lib.pyd in pandas.lib.map_infer(pandas\lib.c:42840)() ValueError: invalid literal for int() with base 10: '2A' ```
有没有一种方法可以为 `myDF['B'].apply()` 添加异常处理呢?
谢谢您的帮助!

感谢@Amit的修复。 - RukTech
3个回答

62

我也有同样的问题,但是情况更普遍,很难判断函数是否会生成异常(即你不能用像 isdigit 这样简单的方式来显式地检查这个条件)。

经过一段时间的思考,我想出了在单独的函数中嵌入try/except语法的解决方法。如果以下示例对任何人有帮助,我将其发布。

import pandas as pd
import numpy as np

x=pd.DataFrame(np.array([['a','a'], [1,2]]))

def augment(x):
    try:
        return int(x)+1
    except:
        return 'error:' + str(x)

x[0].apply(lambda x: augment(x))

5
我认为这回答了问题,而被接受的回答则以不同的方式解决了这个问题。 - janh
我从Pylint得到了一个“不必要的lambda”警告,所以我只是使用了x[0].apply(augment),它会传递它所需的内容。 - Noumenon

20

使用 lambda 实现的一种方法:

myDF['B'].apply(lambda x: int(x) if str(x).isdigit() else None)

对于您的输入:

>>> myDF
    A   B
0  11  11
1  22  2A
2  33  33

[3 rows x 2 columns]

>>> myDF['B'].apply(lambda x: int(x) if str(x).isdigit() else None)
0    11
1   NaN
2    33
Name: B, dtype: float64

1
@RukTech:只是想澄清一下,dtype 是 float64,因为没有 NaN 的整数版本。 - Paul H
在else子句中,可以使用'None'代替None - Amit
@Paul:它是float64类型,我的主要目的是将其从对象转换为数字类型。不过你发现得很好。 - RukTech
如果我不知道错误是什么,我怎么处理异常? - June

15

更好/更快完成:

In [1]: myDF = DataFrame(data=[[11,11],[22,'2A'],[33,33]], columns = ['A','B'])

In [2]: myDF.convert_objects(convert_numeric=True)
Out[2]: 
    A   B
0  11  11
1  22 NaN
2  33  33

[3 rows x 2 columns]

In [3]: myDF.convert_objects(convert_numeric=True).dtypes
Out[3]: 
A      int64
B    float64
dtype: object

这是一种向量化的实现方式。 coerce 标志表示将无法转换为数字的任何内容标记为 nan

当然,您也可以对单个列执行此操作。


6
请注意,自Pandas 0.21.0起,“convert_objects()”已被弃用。 - Ram Narasimhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接