pandas.read_csv遇到转义字符反斜线“/“出错

起因

用pandas.read_csv读取csv文件,结果在读到下面两行的时候总是报错说列数过多:

124832,"Zehut Sh'ula\"",,7,1997,,Z324,124831,1,3,,3ecbb0386bee44d925ff0fcdb11e11b8
80501,"Co-Host Andy Cohen; \"Steel Magnolias\" Cast: Queen Latifah, Alfre Woodard, Jill Scott",,7,2012,,C2353,80464,2,26,,4ec914112555c0fb2180cc7cab41c67

ps:这两行并不相邻
但是肉眼看过去,这两列的数据并没有什么问题,盲猜是引号导致的问题,因为其他地方都很正常,简单尝试删去某个引号后跑通了,但是不理解原因,而且按理说不应该改动数据,于是开始搜索相关问题。

分析

step1

在stackoverflow上看到这样一则问答https://stackoverflow.com/questions/23934613/reading-a-csv-file-to-pandas-error-expected-after,不过这个是引号嵌套使用导致的,和我的情况不太符合,不过让我更加确信是pandas.read_csv在处理引号的时候出了问题。

于是我干脆把上面出问题的两列单拿出来看看pandas到底是怎么读的,创建csv如下:

c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14
124832,"Zehut Sh'ula\"",,7,1997,,Z324,124831,1,3,,3ecbb0386bee44d925ff0fcdb11e11b8
80501,"Co-Host Andy Cohen; \"Steel Magnolias\" Cast: Queen Latifah, Alfre Woodard, Jill Scott",,7,2012,,C2353,80464,2,26,,4ec914112555c0fb2180cc7cab41c671

python代码:

# read csv in this folder named 14or12? with headers
# and show the content of the file

import pandas as pd

df = pd.read_csv('14or12?', sep=',')
# show the content of the file, don't abbreviate
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
print(df)

得到的结果让我大吃一惊,竟然是:

       c1                                                 c2              c3  \
0  124832  Zehut Sh'ula\",,7,1997,,Z324,124831,1,3,,3ecbb...   Alfre Woodard   

             c4  c5  c6    c7  c8     c9    c10  c11  c12  c13  \
0   Jill Scott" NaN   7  2012 NaN  C2353  80464    2   26  NaN   

                                c14  
0  4ec914112555c0fb2180cc7cab41c671

可以看到两行数据变成了一行,c2这列数据明显异常,似乎引号囊括了过多的内容。基本可以猜测是Zehut Sh'ula\"附近的问题

step2

为了进一步确认问题出在哪儿,以及为什么会产生这样的结果,我在Zehut Sh’ula\"处加了一些字母作为tag:

c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14
124832,"Zehut Sh'ula\"aa",,7,1997,,Z324,124831,1,3,,3ecbb0386bee44d925ff0fcdb11e11b8
80501,"Co-Host Andy Cohen; \"Steel Magnolias\" Cast: Queen Latifah, Alfre Woodard, Jill Scott",,7,2012,,C2353,80464,2,26,,4ec914112555c0fb2180cc7cab41c671

输出为:

       c1                                                 c2              c3  \
0  124832                                   Zehut Sh'ula\aa"             NaN   
1   80501  Co-Host Andy Cohen; \Steel Magnolias\" Cast: Q...   Alfre Woodard   

             c4      c5   c6    c7        c8     c9    c10  c11  \
0             7  1997.0  NaN  Z324  124831.0      1      3  NaN   
1   Jill Scott"     NaN  7.0  2012       NaN  C2353  80464  2.0   

                                c12  c13                               c14  
0  3ecbb0386bee44d925ff0fcdb11e11b8  NaN                               NaN

发现结果又变成了两行,似乎正常了一点,但仔细看row0c2处是Zehut Sh'ula\aa",说明read_csv把\"中的"当成了正常的引号,而不是转义后的引号。至于为什么后面的解析又变得正确了,目前不得而知,按照我的理解,结果应该和step1中类似才对,不知道为什么Zehut Sh'ula\aa"中最后的引号被当成了普通字符。

但是可以基本确认问题出在转移字符上,于是开始搜索相关问题。

解决

查了很多问答和博客,都没有找到问题的关键,后面找到了一些博客说pandas.read_csv()默认的转义字符是双引号?如果想表示",就要用引号扩起来,"""这样子(未经证实)

想来原理应该并不是转义字符而是把引号内的内容当做普通字符,但是这就存在一个组合问题,也就是为什么不是把前两个"当做一组,最后的"当做不闭合的引号呢?

总之确定了问题就是pandas并没有把\理解为转义字符,于是去看了文档,加上参数
escapechar='\\'就好了(加两个是因为\本身在python里就是转义字符,需要用\\来表示\本身)。

最终结果

# read csv in this folder named 14or12? with headers
# and show the content of the file

import pandas as pd

df = pd.read_csv('14or12?', sep=',', escapechar='\\')
# show the content of the file, don't abbreviate
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
print(df)
       c1                                                 c2  c3  c4    c5  \
0  124832                                      Zehut Sh'ula" NaN   7  1997   
1   80501  Co-Host Andy Cohen; "Steel Magnolias" Cast: Qu... NaN   7  2012   

   c6     c7      c8  c9  c10  c11                               c12  c13  c14  
0 NaN   Z324  124831   1    3  NaN  3ecbb0386bee44d925ff0fcdb11e11b8  NaN  NaN  
1 NaN  C2353   80464   2   26  NaN  4ec914112555c0fb2180cc7cab41c671  NaN  NaN 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值