Pandas read_csv 转换器 – 如何处理异常 (literal_eval SyntaxError)
Posted
技术标签:
【中文标题】Pandas read_csv 转换器 – 如何处理异常 (literal_eval SyntaxError)【英文标题】:Pandas read_csv converter – How to handle exceptions (literal_eval SyntaxError) 【发布时间】:2019-04-05 18:03:07 【问题描述】:在 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
可以接受或忽略的对象?
注意:我的理解是,在可读文件中包含文字元组并不总是最好的,但在我的情况下它很有用。
【问题讨论】:
【参考方案1】:您可以创建一个有条件地使用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
由 other 而非空值的原因引起。
def literal_converter(val):
try:
return literal_eval(val)
except SyntaxError, ValueError:
return val
【讨论】:
【参考方案2】:我会先正常读取数据,不带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
,尽管它看起来只能在字符串上工作,但在列表和元组上工作得很好。因此,您可以在每列的元组中高效且统一地索引元素。
【讨论】:
以上是关于Pandas read_csv 转换器 – 如何处理异常 (literal_eval SyntaxError)的主要内容,如果未能解决你的问题,请参考以下文章
如何在使用 pandas.read_csv 读取 csv 文件时将 pandas.dataframe 中的元素转换为 np.float?
pandas使用read_csv读取文件数据设置converters参数将百分比字符串转换为数字
python 在pandas中的read_csv时将值转换为demical
Pandas read_csv 转换器 – 如何处理异常 (literal_eval SyntaxError)