【问题标题】:read csv with escape characters使用转义字符读取 csv
【发布时间】:2019-05-28 15:10:31
【问题描述】:

我有一个 csv 文件,其中包含一些文本等。我想标记(拆分为单词列表)此文本,但在 pd.read_csv 如何解释转义字符时遇到问题。

我的 csv 文件如下所示:

text, number
one line\nother line, 12

代码如下:

df = pd.read_csv('test.csv')
word_tokenize(df.iloc[0,0])

输出是:

['one', 'line\\nother', 'line']

而我想要的是:

['one', 'line', 'other', 'line']

问题是pd.read_csv() 没有将\n 解释为换行符,而是解释为两个字符(\n)。

我尝试将escapechar 参数设置为'\''\\',但两者都只是从字符串中删除斜杠而不对换行符进行任何解释,即字符串变为on one linenon other line

如果我明确设置df.iloc[0,0] = 'one line\nother line'word_tokenize 就可以正常工作,因为这次\n 实际上被解释为换行符。

理想情况下,我会简单地更改 pd.read_csv() 解释文件的方式,但其他解决方案也可以。

【问题讨论】:

  • 这两个例子都没有\n。你所有的例子都有一个 ` (read text has it escaped, of course), yet you say all the time that it's \n` (例如“如果我明确设置 df.iloc[0,0] = 'one line\other line',word_tokenize 工作得很好,因为 \n 实际上被解释为换行符这次。” - 但字符串在任何地方都没有\n???)请更正此问题并指定您想要的内容(\n 或 `` 用作换行符)。
  • 您可以遍历您的输出并执行split('\'),如果其中的字符“\”,它将把一个字符串分成两部分。更多信息:geeksforgeeks.org/python-string-split 但这不是很理想
  • @h4z3 将文本中的所有\ 更正为\n,因为它们应该是。我希望将 \n 解释为换行符。
  • 好的。它加载文本并转义反斜杠,因此它实际上与加载的内容相同(未转换为换行符)。为了让它成为一个换行符,你需要用双反斜杠代替一个。如果您打印整个数组,它将是 ['one', 'line\nother', 'line'] 但如果您手动打印 list[1] ,它将解释换行符 - 就像您在评论中想要的那样。但是您的帖子说要在\n 上拆分,这是另一回事...
  • Tbh 将此作为真正的 csv 读取(其中新行表示新行),我可能会将整个内容作为普通文本文件读取(例如,通过循环中的行),替换双反斜杠使用单个,然后将整个内容解释为 csv(在两者之间保存或不保存,具体取决于大小以及您处理原始文件和替换的方式) - 两个“行”之前由文本 \n 而不是物理换行符分隔现在由物理换行符分隔,因此被解释为这样。

标签: python pandas csv


【解决方案1】:

这个问题措辞有点糟糕。我猜pandas 转义字符串中的\ 会让人困惑nltk.word_tokenizepandas.read_csv 只能使用一个分隔符(或正则表达式,但我怀疑你是否想要那个),因此它将始终将文本列读取为 "one line\nother line",并转义反斜杠以保留它。如果您想进一步解析和格式化它,您可以使用转换器。这是一个例子:

import pandas as pd
import re

df = pd.read_csv(
         "file.csv", converters={"text":lambda s: re.split("\\\\n| ", s)}
)

以上结果为:

                       text   number
0  [one, line, other, line]       12

编辑:如果您需要使用 nltk 进行拆分(比如说拆分取决于语言模型),您需要在传递给 word_tokenize 之前取消转义字符串;试试这样的:

lambda s: word_tokenize(s.encode('utf-8').decode('unicode_escape')

注意:查询中的匹配列表非常棘手,因此您可能希望通过像这样更改 lambda 来将它们转换为元组:

lambda s: tuple(re.split("\\\\n| ", s))

【讨论】:

  • 已编辑问题,字符串中的 \ 应该是 \nword_tokenize 来自nltk
  • 在这种情况下,您可以将正则表达式更新为"\\\\n| ",它应该可以工作(在我的答案中更新)。
  • @Kaio 我添加了一些额外的注释,也许会有所帮助。
【解决方案2】:

你可以试试这个

import pandas as pd

df = pd.read_csv("test.csv", header=None)
df = df.apply(lambda x: x.str.replace('\\', " "))
print(df.iloc[1, 0])

# output: one line other line 

【讨论】:

    【解决方案3】:

    在你的情况下,只需使用:

    data = pd.read_csv('test.csv', sep='\\,', names=['c1', 'c2', 'c3', 'c4'], engine='python')
    

    【讨论】:

    • 这不起作用,我还有其他用逗号分隔的字段。列名已经在文件的第一行给出。
    • @Kaio 然后你需要在 python 引擎中使用正则表达式。我更新了我的代码
    • 仍然无法正常工作,我的 DataFrame 中有很多 NaN。请参阅我提供的示例文件。
    • @Kaio 我没有看到任何文件
    • 它的内容在问题的第一个“代码框”中。另外我已经接受了一个答案,也许看看我制作的措辞更好的版本here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2017-01-20
    • 2018-07-25
    • 2022-01-22
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多