【问题标题】:Pandas Unable to Read CSV file using pandas, with extra quote char熊猫无法使用熊猫读取 CSV 文件,带有额外的引号字符
【发布时间】:2019-10-15 17:18:38
【问题描述】:

我有以下 CSV 和以下条目

“第 1 列”| “列2”| “第 3 列”| “第 4 列”| “第 5 栏”
“123” | “sometext”、“this somedata”、“8 英寸”、“你好”

当我尝试读取 8 inches" 时出现问题,我无法使用 read_csv() 读取 csv。

Pandas.read_csv(io.BytesIO(obj['Body'].read()), sep="|",
                                      quoting=1,
                                      engine='c', error_bad_lines=False, warn_bad_lines=True,
                                      encoding="utf-8", converters=pandas_config['converters'],skipinitialspace=True,escapechar='\"')

有没有办法处理单元格内的引号。

【问题讨论】:

  • 错误是什么?这确实是 .csv 文件的问题。我可能会在输入文件上运行一个脚本来解决引用问题。是否也有两种分隔符(|,)?还是最后一个栏和行尾之间的整个条目是一列?你能包括你正在使用的转换器吗?
  • @mgrollins:只有| 作为分隔符,问题实际上在于 csv 文件,但这是一种特殊情况,我在字符串中得到双引号
  • @mgrollins:这是错误Exception while performing pandas.read_csv operation. error: Error tokenizing data. C error: EOF inside string starting at row 0, pandas config:
  • 你能在读入之前清理来自obj['Body'] 的输入吗?您确定行尾之前的第一行中没有空字符吗?

标签: python pandas csv


【解决方案1】:

从为此案例传递适当的参数开始:

  1. sep='[|,]' - 有 两个 分隔符:一个 管道 字符和一个 逗号, 所以将它们定义为 regex
  2. skipinitialspace=True - 您的源文本包含额外的空格(在 分隔符),所以你应该删除它们。
  3. engine='python' - 抑制有关回退到 “python”引擎

上述选项单独允许调用 read_csv 没有错误,但缺点 (现在)是双引号仍然存在。

要至少从数据行中消除它们,还需要另一个技巧:

定义一个转换器(lambda)函数:

cnv = lambda txt: txt.replace('"', '')

并将其应用于所有源列。

在您的情况下,您有 5 列,因此为了保持代码简洁, 你可以使用字典理解

{ i: cnv for i in range(5) }

所以整个代码可以是:

df = pd.read_csv(io.StringIO(txt), sep='[|,]', skipinitialspace=True,
    engine='python', converters={ i: cnv for i in range(5) })

结果是:

  "column1"  "column2"       "column3"  "column4"  "column5"
0      123    sometext   this somedata   8 inches      hello

但是请记住,现在所有的列都是 string 类型的,所以你应该 将所需的列转换为数字。 另一种方法是为数字列传递第二个转换器, 返回 数字 而不是字符串。

要获得正确的列名(不带双引号),您可以传递其他参数:

  • skiprows=1 - 省略第一行,
  • names=["column1", "column2", "column3", "column4", "column5"] - 到 自行定义列列表。

【讨论】:

  • 感谢您的信息,假设我有适当的转换器,我在日期时间列上失败了
  • 如果您的日期时间字段转换器失败,那么很可能问题出在此转换器中。要调查此问题,请针对一些输入数据案例调用此类转换器,查看结果并更正转换器以返回正确的结果。
【解决方案2】:

我们可以指定一个稍微复杂的分隔符,读取数据并去除多余的引号字符:

# Test data:
text='''"column1"| "column2"| "column3"| "column4"| "column5" 
        "123" | "sometext", "this somedata", "8 inches"", "hello"'''
ff=io.StringIO(text)


df= pd.read_csv(ff,sep=r'"\s*[|,]\s*"',engine="python")
# Make it tidy:
df= df.transform(lambda s: s.str.strip('"'))
df.columns= ["column1"]+list(df.columns[1:-1])+["column5"]

结果:

  column1   column2        column3   column4 column5
0     123  sometext  this somedata  8 inches   hello

【讨论】:

  • 我收到最后一列的错误,在我的实际情况下是日期时间列,你可以说我的 column5 是日期时间类型,我收到此错误Exception while performing pandas.read_csv operation. error: 'RECORD_CREATED_TIMESTAMP' is not in list,虽然我有这是我的转换器列表
猜你喜欢
  • 1970-01-01
  • 2015-12-21
  • 1970-01-01
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 2021-07-06
  • 2020-10-01
相关资源
最近更新 更多