如何在Python / Pandas中处理许多不同类型的valueError结果?

时间:2017-07-25 22:56:23

标签: python pandas try-except valueerror

我正在尝试从具有多种可能性的dirty输入中提取值。

输入是一个具有多种可能类型的系列,例如:"8673331000", "8673331000'", 8673331000, 18673331000, 8673331000.0, NaN, "867B331000"

在前5个案例中,我正在寻找867333格式的int。最后两个案例我想报告Unknown或其他相似的事情。

我一直在使用try / except,但报告了许多不同类型的ValueError

现在我正在使用:

*try:
    val = int(number)
except ValueError as ve:
    if (number[len(number)-1]=="'"):
        val = int(number[0:len(number)-2])
    else:
        val = int(float(number))*

except子句处理输入具有单引号但不处理NaN情况的情况。

感谢您的想法。

2 个答案:

答案 0 :(得分:0)

如果输入已经是pandas系列,您可以使用pandas.to_numeric(your_series_data, errors='coerce').fillna(-9999).astype(int)

import pandas as pd
from io import StringIO

# some example data
data=StringIO('''Values
,8673331000
,8673331000
,8673331000
,18673331000
,8673331000.0
,NaN
,867B331000
''')

#read data to csv
df = pd.read_csv(data, sep=",")

# your data may already be a pandas series, which below is df.iloc[:,0]
pd.to_numeric(df.iloc[:,0],errors='coerce').fillna(-9999).astype(int)

NaN     8673331000 
NaN     8673331000
NaN     8673331000
NaN    18673331000
NaN     8673331000
NaN          -9999
NaN          -9999
Name: Values, dtype: int64

您可以直接使用此系列的值,而无需使用try / except将它们强制转换为整数。

整数不能在pandas中表示为NaN,因此在示例中它们将替换为-9999。当你从系列中提取值时,如果它与-9999匹配,你可以将它设置为None或你的代码应该具有缺失值的任何值。

如果您的输入值是字符串,则可能会强制转换为NaN而不是整数,例如

data=StringIO('''Values
,8673331000
,"8673331000"
,\'8673331000\'
,18673331000
,8673331000.0
,NaN
,867B331000
''')
df = pd.read_csv(data, sep=",")

使用pd.to_numeric(df.iloc[:,0], errors='coerce').fillna(-9999).astype(int)时,第3个值将以NaN结尾在这种情况下,我建议只删除输入数据中的所有“或”

希望有所帮助!

答案 1 :(得分:0)

最后,我决定使用正则表达式精心设计if / elif子句。我怀疑嵌套的try / except会起作用,但是假设valueError可以由许多不同的可能性产生,我坚持使用前者。

这是我登陆的内容,为了简单起见进行了一些编辑

def get_code(输入,记录器):     #抓取可以以形式出现的原始输入的整数形式     #an int,float,string(例如8673341000,18673341000," 8673341000",     #" 8673341000'"," 8673341000"," 867BBA1000",8673341000.0,NaN     #return" Unknown"如果提供了难以辨认的输入

import re
import math
import numpy as np

val = "Unknown"

if (type(input)==int):
    val = input

elif(type(input)==float):
    #could be NaN or a float (e.g. 100.0, but not 1.0e+10)
    try:
        val= int(input)
    except:
        val="Unknown"

elif(type(input)==str):
    if (input[len(input)-1]=="'"):
        val = int(input[0:len(input)-1])
    elif (re.match('^[0-9]+$', input)):
        #input contains only digits
        val = int(input)
    elif ((re.match('\s+\d+\s+', input)) or (re.match('\s+\d+', input)) or (re.match('\d+\s+', input))):
        #leading or trailing spaces
        input = input.strip()
        val=int(input)
    else:
        return "Unknown"
elif(type(np.float64(input).item())==float):
    #Input is of the form 1.416441e+10

    val = int(input)


else:
    logger.warning("Unknown Input type for get_NPANXX() ... input:" , input)
    logger.warning(type(input))
    return val #E.g. "Unknown Input"

#...more processing once val is in integer form
return