Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 比较两个大文件并合并匹配信息_Python_Json_Python 3.x_Csv_Multiprocessing - Fatal编程技术网

Python 比较两个大文件并合并匹配信息

Python 比较两个大文件并合并匹配信息,python,json,python-3.x,csv,multiprocessing,Python,Json,Python 3.x,Csv,Multiprocessing,我有两个相当大的文件,JSON(185000行)和CSV(650000行)。我需要遍历JSON文件中的每个dict,然后在该文件中遍历part_numbers中的每个部分,并对其进行比较,以获得CSV中该部分的前三个字母 出于某种原因,我很难把这件事做好。我的脚本的第一个版本太慢了,所以我试图加快它 JSON示例: [ {"category": "Dryer Parts", "part_numbers": ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR"

我有两个相当大的文件,JSON(185000行)和CSV(650000行)。我需要遍历JSON文件中的每个dict,然后在该文件中遍历
part_numbers
中的每个部分,并对其进行比较,以获得CSV中该部分的前三个字母

出于某种原因,我很难把这件事做好。我的脚本的第一个版本太慢了,所以我试图加快它

JSON示例:

[
    {"category": "Dryer Parts", "part_numbers": ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR"], "parent_category": "Dryers"},
    {"category": "Washer Parts", "part_numbers": ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR"], "parent_category": "Washers"},
    {"category": "Sink Parts", "part_numbers": ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR"], "parent_category": "Sinks"},
    {"category": "Other Parts", "part_numbers": ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR"], "parent_category": "Others"}
]
CSV:

WCI|ABC
WPL|DEF
BSH|GHI
WCI|JKL
结束语如下所示:

{"category": "Other Parts",
 "part_numbers": ["WCIABC","WPLDEF","BSHGHI","JKLWCI"...]}
下面是一个我到目前为止所做的示例,它在
if(part.rstrip()==row[1]):
处返回
索引器:列表索引超出范围


我想我找到了。您的CSV阅读器与许多其他文件访问方法类似:您按顺序读取文件,然后点击EOF。当您尝试对第二部分执行相同操作时,该文件已处于EOF,并且第一次
读取
尝试返回空结果;这没有第二个元素

如果要再次访问所有记录,需要重置文件书签。最简单的方法是使用

partfile.seek(0)
另一种方法是关闭并重新打开文件


这会让你行动起来吗?

只要csv中存在所有零件号,这就应该有效

import json

# read part codes into a dictionary
with open('partfile.csv') as fp:
    partcodes = {}
    for line in fp:
        code, number = line.strip().split('|')
        partcodes[number] = code

with open('catparts.json') as fp:
    catparts = json.load(fp)

# modify the part numbers/codes 
for cat in catparts:
    cat['part_numbers'] = [partcodes[n] + n for n in cat['part_numbers']]

# output
with open('output.json', 'w') as fp:
    json.dump(catparts, fp)

正如我在评论中所说,您的代码(现在)给了我一个
name错误:名称“reader”
未在
find\u part()函数中定义。修复方法是将
csv.reader
的创建移到函数中。我还更改了文件的打开方式,使用带有上下文管理器的
换行符的
参数。这也解决了一系列单独的任务都试图同时读取同一个csv文件的问题

您的方法非常低效,因为它读取
项['part\u number']
中每个零件的整个
'partfile.csv'
文件。尽管如此,以下措施似乎有效:

import csv
import json
from multiprocessing import Pool

def find_part(item):
    data = {
        'parent_category': item['parent_category'],
        'category': item['category'],
        'part_numbers': []
    }

    for part in item['part_numbers']:
        with open('partfile.csv', newline='') as partfile:  # open csv in Py 3.x
            for row in csv.reader(partfile, delimiter='|'):
                if part.rstrip() == row[1]:
                    data['part_numbers'].append(row[0] + row[1])

    with open('output.json', 'a') as outfile:
        outfile.write('    ')
        json.dump(data, outfile)
        outfile.write(',\n')

if __name__ == '__main__':
    catparts = json.load(open('carparts.json', 'r'))

    with open('output.json', 'w+') as outfile:
        outfile.write('[\n')

    p = Pool(50)
    p.map(find_part, catparts)

    with open('output.json', 'a') as outfile:
        outfile.write(']')
这里有一个效率更高的版本,每个子流程只读取一次整个
'partfile.csv'
文件

import csv
import json
from multiprocessing import Pool

def find_part(item):
    data = {
        'parent_category': item['parent_category'],
        'category': item['category'],
        'part_numbers': []
    }

    with open('partfile.csv', newline='') as partfile:  # open csv for reading in Py 3.x
        partlist = [row for row in csv.reader(partfile, delimiter='|')]

    for part in item['part_numbers']:
        part = part.rstrip()
        for row in partlist:
            if row[1] == part:
                data['part_numbers'].append(row[0] + row[1])

    with open('output.json', 'a') as outfile:
        outfile.write('    ')
        json.dump(data, outfile)
        outfile.write(',\n')

if __name__ == '__main__':
    catparts = json.load(open('carparts.json', 'r'))

    with open('output.json', 'w+') as outfile:
        outfile.write('[\n')

    p = Pool(50)
    p.map(find_part, catparts)

    with open('output.json', 'a') as outfile:
        outfile.write(']')
虽然可以将
'partfile.csv'
数据读入主任务中的内存,并将其作为参数传递给
find_part()
子任务,但这样做只意味着每个进程都必须对数据进行pickle和unpickle。您需要运行一些计时测试,以确定这是否比使用
csv
模块显式读取要快,如上所示


还要注意的是,在将任务提交到
池之前,预处理
'carparts.json'
文件中的数据加载,并从每行的第一个元素中去掉尾随的空格,这样会更有效,因为这样您就不需要在
find\u part()中执行
part=part.rstrip()
一遍又一遍。同样,我也不知道这样做是否值得,只有计时测试才能确定答案。

此时的
行是什么?您以前处理过多少行?另外,你可以发布最小的代码(根据发布指南),或者文件读取是问题的关键部分吗?文件读取并不是真正的问题。更重要的是如何有效地做到这一点。你还需要什么代码?不要更多代码。。。较少的但是,我想我在无法运行代码的情况下发现了它。当我使用示例输入文件运行代码时,我在
'parent\u category'
行上得到一个
keyrorm:'parent\u category'
find\u part()
函数中的项['parent\u category'],
,因此我无法重现“不正确的索引错误”提到问题。@martineau抱歉!我使用的密钥忘记包含在json示例中。缺少家长分类
谢谢您的回答。将
与open()一起使用
与仅使用类似的东西有什么区别:
file=open('file','r')
?另外,我收到了一个代码错误:
ValueError:太多的值无法解压缩(预期为2)
我猜这是由于文件太大。CSV有650000行,JSON文件有185000行,这可能是由于partfile.CSV中的某行包含多个
引起的。这只是示例代码,所以我对一致的输入数据做了一些假设。在生产代码中,您必须处理格式错误的输入。感谢您的输入!我将在何处将此代码段添加到我的代码中?如果要返回到文件的开头,请插入该代码段。这在您的控制和数据流中的位置如何?这个答案会导致多个进程试图打开文件时出现问题吗?@RyanScottCady:不会,这不会导致问题,因为所有进程都只是试图读取文件。
partfile.csv
很大吗?
partfile.csv
是650k行。所以它不是超大的。我想知道是否有一个问题,只是把它的内容读入字典哈哈。我尝试了你的解决方案,但它是有效的!Ryan:按照今天的标准,这不是很大,所以你可以把它读入内存并传递给每个进程。不过,这样做会带来一些开销——每个进程都需要进行酸洗和取消酸洗,这可能不会快很多。我正在寻找一个解决方案,并将相应地更新我的答案,如果它证明是可行的,这是。。。
import csv
import json
from multiprocessing import Pool

def find_part(item):
    data = {
        'parent_category': item['parent_category'],
        'category': item['category'],
        'part_numbers': []
    }

    with open('partfile.csv', newline='') as partfile:  # open csv for reading in Py 3.x
        partlist = [row for row in csv.reader(partfile, delimiter='|')]

    for part in item['part_numbers']:
        part = part.rstrip()
        for row in partlist:
            if row[1] == part:
                data['part_numbers'].append(row[0] + row[1])

    with open('output.json', 'a') as outfile:
        outfile.write('    ')
        json.dump(data, outfile)
        outfile.write(',\n')

if __name__ == '__main__':
    catparts = json.load(open('carparts.json', 'r'))

    with open('output.json', 'w+') as outfile:
        outfile.write('[\n')

    p = Pool(50)
    p.map(find_part, catparts)

    with open('output.json', 'a') as outfile:
        outfile.write(']')