
[英]How to use ast.literal_eval in a pandas dataframe and handle exceptions
[英]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.