Pandas .apply() 函数中的异常处理
如果我有一个数据框(DataFrame):
myDF = DataFrame(data=[[11,11],[22,'2A'],[33,33]], columns = ['A','B'])
这会给出以下的数据框(我刚开始在stackoverflow上发帖,没足够的声望上传数据框的图片)
| 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 在 pandas.lib.map_infer (pandas\lib.c:42840)()
ValueError: invalid literal for int() with base 10: '2A'
有没有办法给 myDF['B'].apply() 添加异常处理呢?
提前谢谢你!
3 个回答
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
65
我也有过同样的问题,不过我遇到的情况更复杂,难以判断这个函数是否会产生错误(也就是说,不能像用 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))
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
。
当然,如果你愿意,也可以只对单独的一列这样做。