如何正确读取包含单引号的CSV文件?

3

尝试读取.csv文件,其中行看起来像这样:

gif,940ff2312-4325-8898dfs-9ce1ca56c5sfb,'[{"mid": "/m/083dsf", "description": "buff", "probability": 0.9663228988647461, "topic": 0.9663228988647461}]'

我需要读取这些行并将其放入两个列表中:gifbif。每个列表必须包含一对元组:第一个字符串(在我的示例中为'gif'),字典列表(在单引号中的第三个元素是我的示例)。

由于read_csv会引发错误,因此无法正确解析它。尝试了简单的字符串方法,它有效,但修复字典列表很麻烦,我认为这不好/不优化。尝试了JSON - 不起作用。

以下是我的方法:

gif = []
bif = []

with open('file.csv', 'r', encoding = 'utf-8') as file:
    lines = file.readlines()
    for line in lines:
        obj = line[:line.find(',')]
        arr = line[line.find('['):-2]
        json_acceptable_string = arr.replace("'", "\"")
        arr = json.loads(json_acceptable_string)
        
        if obj == 'gif':
            gif.append((obj, arr))
        elif obj == 'bif':
            bif.append((obj, arr))

你有什么解决方法吗?也许在pandas中有一些误解和好的技巧?

更新:我也尝试了这种方式:

import csv

gif = []
bif = []

with open('file.csv', 'rt', encoding='utf-8') as file:
    csv_reader = csv.reader(file, delimiter=',', quotechar="'")
    for line in csv_reader:
        for obj, Id, objArr in line: # here I'm trying to split it in 3 objects
            if obj == 'gif':
                gif.append((obj, arr))
            elif obj == 'bif':
                bif.append((obj, arr))

但它引发了:
ValueError: too many values to unpack (expected 3)

不确定你的目标是什么。你可以像这样读取文件:df=pd.read_csv("touch.csv",header=None,quotechar="'",names=['key','code','arr']),然后可以像这样构建JSON:values=[json.dumps(each) for each in df['arr']]。如果你能展示你想要的输出,我可以更具体地回答。 - undefined
如果你遇到错误,请打印出错的那一行。 - undefined
ValueError是正确的 - 你试图每次迭代3个项目,而只有1个项目(item)可用。你必须用以下代码替换第二个for循环:obj, Id, objArr = *line - 然而,由于它依赖于解包和解析行长度相同,这是不清楚的,应该避免使用。你可以使用以下代码:obj = line[0]Id = line[1]objArr = line[1],这样更清晰但更冗长。 - undefined
让我们在聊天中继续这个讨论。点击此处进入聊天室 - undefined
@simpleApp,这是一个不错的方法,每个json.dumps()后面需要添加json.loads(),但我无法弄清楚为什么结果仍然是字符串,而不是字典... - undefined
显示剩余8条评论
2个回答

4
你可以使用quotechar 格式参数来正确解析单引号 JSON 字符串:
import csv
with open('file.csv') as csv_file:
    reader = csv.reader(csv_file, delimiter=',', quotechar="'")
    for row in reader:
        print(row)
        # If you want to parse the json, you can do:
        # `json.loads(row[-1])` (requires the json module)
        # Kudos to @juanpa.arrivillaga for the suggestion!

根据您提供的样本数据,这将产生以下输出结果,如所需:
['gif', 
 '940ff2312-4325-8898dfs-9ce1ca56c5sfb', 
 '[{"mid": "/m/083dsf", "description": "buff", "probability": 0.9663228988647461, "topic": 0.9663228988647461}]']

好的回答,为了完整起见,你可以直接显示op json.loads(row[2]) - undefined
抱歉,忘了提到我也使用了csv.reader,但是出现了一个错误。我会更新帖子并附上错误信息,请你检查一下。 - undefined
@juanpa.arrivillaga:谢谢!这是个好主意 - 已编辑。 - undefined
@taciturno:你得到了什么错误?我使用了你提供的示例数据以及其他一些生成的数据,它们都可以正确解析这段代码片段。 - undefined

0
在CSV文件中,数据如下: gif,940ff2312-4325-8898dfs-9ce1ca56c5sfb,'[{"mid": "/m/083dsf", "description": "buff", "probability": 0.9663228988647461, "topic": 0.9663228988647461}]' 要处理单引号中的数组,可以使用pandas的read_csv构造函数中的 "quotechar="'"
作为数据帧读取:
df=pd.read_csv("touch.csv",header=None,quotechar="'",names=['key','code','arr'])

一种方法是将其转储为 JSON 格式:

import json
for each in df['arr']:
    my_json=json.dumps(each)
    print(my_json)

另一种方法可以被视为字典数据结构,ast模块在这里非常方便。因此,将其作为字符串读取并将其转换为字典。

my_list_of_dictionary=[ast.literal_eval (each.replace("[","").replace("]","")) for each in df['arr'] ]
for each_dict in my_list_of_dictionary:
    print(f"Type:{type(each_dict)} value: {each_dict}")

输出: 在此输入图片描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接