在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:我的理解是,在可读文件中包含文字元组并不总是最好的选择,但对我而言,这很有用。
答案 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}}