熊猫read_csv转换器–如何处理异常(literal_eval SyntaxError)

时间:2018-11-01 13:43:25

标签: python pandas csv literals

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

          A              B
  +--------------+---------------+
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元组对象-但前提是没有空单元格。因为我的单元格为空,所以出现错误:

  

SyntaxError:解析时出现意外的EOF

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

  

ast使用compile来编译源字符串(必须是   表达式)转换成AST。如果源字符串无效   表达式(例如一个空字符串),将引发SyntaxError   编译。

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

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

NB:我的理解是,在可读文件中包含文字元组并不总是最好的选择,但对我而言,这很有用。

2 个答案:

答案 0 :(得分:5)

我将首先正常读取数据,而不使用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尽管看起来只能在字符串上使用,但在列表和元组上也可以正常使用。因此,您可以高效且统一地索引每列元组中的元素。

答案 1 :(得分:4)

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

except

或者,您可以使用SyntaxError / SyntaxError来捕获ValueError。此解决方案比较宽容,因为它可以处理其他格式错误的语法,即def literal_converter(val): try: return literal_eval(val) except SyntaxError, ValueError: return val / {{1}}是由 other 原因而非空值引起的。

{{1}}