如何解析下面的行,以便它将第三列作为 Python 中的列表

how to parse line below so that it will preseve the third column as a list in python

提问人:Kushal Desai 提问时间:7/22/2023 最后编辑:shaik moeedKushal Desai 更新时间:7/22/2023 访问量:58

问:

如何使用 pandas 或 CSV 类型模块解析此行

col1, col2, col3 <br>
name, date, ["data"] <br>
name, date, ["data", "data2", "data3"]  <br>
name, date, ["data1", "data2"] <br>

这是文件的格式。

如果我使用

pd.read_csv(file)

我收到此错误

pandas.errors.ParserError: Error tokenizing data. C error: Expected 3 fields in line 3, saw 5 
Python Pandas CSV 解析

评论

0赞 CtrlZ 7/22/2023
可能是 pandas 和 csv 都无法处理这个问题。您可以使用应用于每行的正则表达式(re 模块)自行处理文件。另外,<br>是否以文本形式存在于文件中,或者这只是指示换行符的方式?
0赞 Serge Ballesta 7/22/2023
这不是一个合法的 csv 文件,因此没有真正的 csv 解析器能够处理它。我只能想象一种解决方法:构建自定义解析器。但恕我直言,真正的方法是仔细检查该文件的来源,并在可能的情况下在上一步中修复其格式。
0赞 Kushal Desai 7/23/2023
对不起,这是我第一次问问题,堆栈溢出抱怨一些格式。所以 <br> 不是列。

答:

0赞 Anay 7/22/2023 #1

由于第三列包含字符串格式的数据,因此请考虑使用 and 参数将字符串表示形式转换为实际列表。StringIOconverters

import pandas as pd
from io import StringIO
import ast

# Your data 
data = ...

# Coverting data into string representation
data_file = StringIO(data)

# Converter function to convert the string representation of lists to actual lists
def parse_list(s):
    return ast.literal_eval(s)

df = pd.read_csv(data_file, converters={'col3': parse_list})
print(df)

评论

0赞 shaik moeed 7/22/2023
在发布答案之前进行测试。这仍然给出相同的错误。
0赞 Anay 7/22/2023
哎呀!我的坏...
0赞 shaik moeed 7/22/2023 #2

尝试忽略方括号之间的逗号,delimiter=', (?![^\[]*[\]])'

import io
data = '''col1, col2, col3 <br>
name, date, ["data"] <br>
name, date, ["data", "data2", "data3"]  <br>
name, date, ["data1", "data2"] <br>'''

df = pd.read_csv(io.StringIO(data),delimiter=', (?![^\[]*[\]])', engine="python")
print(df)

输出:

   col1   col2                          col3 <br>
0  name   date                      ["data"] <br>
1  name   date   ["data", "data2", "data3"]  <br>
2  name   date            ["data1", "data2"] <br>

要删除 ,<br>

# To remove <br> tags from each line
df.rename(columns={'col3 <br>':'col3'}, inplace=True)
df['col3'] = df['col3'].apply(lambda x : x.replace(' <br>', '').strip())

>>> output
   col1  col2                        col3
0  name  date                    ["data"]
1  name  date  ["data", "data2", "data3"]
2  name  date          ["data1", "data2"]
0赞 PaulS 7/22/2023 #3

另一个可能的解决方案:

from io import StringIO

df = pd.read_csv(StringIO(text), sep=r', (?!\")|\s+\<br\>',
             engine='python').dropna(axis=1)

输出:

   col1  col2                        col3
0  name  date                    ["data"]
1  name  date  ["data", "data2", "data3"]
2  name  date          ["data1", "data2"]