繁体   English   中英

Pandas read_csv 转换器——如何处理异常(literal_eval SyntaxError)

[英]Pandas read_csv converter – How to handle exceptions (literal_eval SyntaxError)

在 Pandas DataFrame 中,我正在读取一个如下所示的 csv 文件:

 AB +--------------+---------------+ 0 | | ("t1", "t2") | +--------------+---------------+ 1 | ("t3", "t4") | | +--------------+---------------+

其中两个单元格中有文字元组,其中两个单元格是空的。

df = pd.read_csv(my_file.csv, dtype=str, delimiter=',',
    converters={'A': ast.literal_eval, 'B': ast.literal_eval})

转换器ast.literal_eval可以很好地将文字元组转换为代码中的 Python 元组对象——但ast.literal_eval是没有空单元格。 因为我有空单元格,所以出现错误:

SyntaxError:解析时出现意外的 EOF

根据这个S/O answer ,我应该尝试捕获空字符串的 SyntaxError 异常:

ast 使用 compile 将源字符串(必须是表达式)编译为 AST。 如果源字符串不是有效的表达式(如空字符串),则编译将引发 SyntaxError。

但是,我不确定如何在read_csv converters的上下文中捕获单个单元格的异常。

解决这个问题的最佳方法是什么? 是否有其他方法可以将空字符串/单元格转换为literal_eval会接受或忽略的对象?

注意:我的理解是,在可读文件中包含文字元组并不总是最好的,但在我的情况下它很有用。

您可以创建一个有条件地使用ast.literal_eval的自定义函数:

from ast import literal_eval
from io import StringIO

# replicate csv file
x = StringIO("""A,B
,"('t1', 't2')"
"('t3', 't4')",""")

def literal_converter(val):
    # replace first val with '' or some other null identifier if required
    return val if val == '' else literal_eval(val)

df = pd.read_csv(x, delimiter=',', converters=dict.fromkeys('AB', literal_converter))

print(df)

          A         B
0            (t1, t2)
1  (t3, t4)          

或者,您可以使用try / except来捕获SyntaxError 该解决方案是因为它会处理其他的语法错误比较宽大,即SyntaxError / ValueError造成比空值的其他原因。

def literal_converter(val):
    try:
        return literal_eval(val)
    except SyntaxError, ValueError:
        return val

我首先会literal_eval()读取数据,没有literal_eval() 这给了我们:

              A             B
0           NaN  ("t1", "t2")
1  ("t3", "t4")           NaN

然后我会这样做:

df.fillna('()').applymap(ast.literal_eval)

这使:

          A         B
0        ()  (t1, t2)
1  (t3, t4)        ()

我认为在所有单元格中都有元组很方便,即使是空单元格也是如此。 这将使以后更容易对元组进行操作,例如:

newdf.sum(axis=1)

这给了你:

0    (t1, t2)
1    (t3, t4)

因为“添加”元组是串联。 甚至更棘手但仍然非常有用:

newdf.A.str[0]

给你:

0    NaN
1     t3

因为pd.Series.str尽管看起来只适用于字符串,但适用于列表和元组。 因此,您可以高效且统一地为每列的元组中的元素编制索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM