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

45 投票
3 回答
74578 浏览
提问于 2025-04-18 01:14

如果我有一个数据框(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

当然,如果你愿意,也可以只对单独的一列这样做。

撰写回答