Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.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中实现更快的文件I/O?_Python_Python 3.x_Performance_File Io_Io - Fatal编程技术网

如何在Python中实现更快的文件I/O?

如何在Python中实现更快的文件I/O?,python,python-3.x,performance,file-io,io,Python,Python 3.x,Performance,File Io,Io,关于Python,我有一个与速度/效率相关的问题: 我需要从一个嵌套的JSON文件中提取多个字段(在写入.txt文件后,它们有~64k行,当前代码段在~9分钟内完成),其中每一行都可以包含浮点数和字符串 通常,我只需将所有数据放入numpy中,然后使用np.savetxt()保存它 我已经求助于简单地把线组装成线,但这相当缓慢。到目前为止,我正在做: 将每一行组合为字符串(从JSON中提取所需字段) 将字符串写入相关文件 我对此有几个问题: 这导致了更多独立的file.write()命令,

关于Python,我有一个与速度/效率相关的问题:

我需要从一个嵌套的JSON文件中提取多个字段(在写入
.txt
文件后,它们有~64k行,当前代码段在~9分钟内完成),其中每一行都可以包含浮点数和字符串

通常,我只需将所有数据放入
numpy
中,然后使用
np.savetxt()
保存它

我已经求助于简单地把线组装成线,但这相当缓慢。到目前为止,我正在做:

  • 将每一行组合为字符串(从JSON中提取所需字段)
  • 将字符串写入相关文件
我对此有几个问题:

  • 这导致了更多独立的
    file.write()
    命令,它们也非常慢(大约64k*8个调用(对于8个文件))
所以我的问题是:

  • 什么是解决这类问题的好方法?一种平衡
    速度与内存消耗
    的方法,以实现最高效的磁盘写入
  • 我应该增加我的
    默认缓冲区大小吗?(目前为8192)
我已经检查了这个和这个,但没有什么帮助,除了(根据我的理解,经过检查后,文件io应该已经在python 3.6.x中进行了缓冲),我发现我的默认
default\u BUFFER\u SIZE
8192

这是我的片段的一部分-

def read_json_line(line=None):
    result = None
    try:        
        result = json.loads(line)
    except Exception as e:      
        # Find the offending character index:
        idx_to_replace = int(str(e).split(' ')[-1].replace(')',''))      
        # Remove the offending character:
        new_line = list(line)
        new_line[idx_to_replace] = ' '
        new_line = ''.join(new_line)     
        return read_json_line(line=new_line)
    return result

def extract_features_and_write(path_to_data, inp_filename, is_train=True):
    # It's currently having 8 lines of file.write(), which is probably making it slow as writing to disk is  involving a lot of overheads as well
    features = ['meta_tags__twitter-data1', 'url', 'meta_tags__article-author', 'domain', 'title', 'published__$date',\
                'content', 'meta_tags__twitter-description']
    
    prefix = 'train' if is_train else 'test'
    
    feature_files = [open(os.path.join(path_to_data,'{}_{}.txt'.format(prefix, feat)),'w', encoding='utf-8')
                    for feat in features]
    
    with open(os.path.join(PATH_TO_RAW_DATA, inp_filename), 
              encoding='utf-8') as inp_json_file:
​
        for line in tqdm_notebook(inp_json_file):
            for idx, features in enumerate(features):
                json_data = read_json_line(line)  
​
                content = json_data['meta_tags']["twitter:data1"].replace('\n', ' ').replace('\r', ' ').split()[0]
                feature_files[0].write(content + '\n')
​
                content = json_data['url'].split('/')[-1].lower()
                feature_files[1].write(content + '\n')
​
                content = json_data['meta_tags']['article:author'].split('/')[-1].replace('@','').lower()
                feature_files[2].write(content + '\n')
​
                content = json_data['domain']
                feature_files[3].write(content + '\n')
​
                content = json_data['title'].replace('\n', ' ').replace('\r', ' ').lower()
                feature_files[4].write(content + '\n')
​
                content = json_data['published']['$date']
                feature_files[5].write(content + '\n')
​
                content = json_data['content'].replace('\n', ' ').replace('\r', ' ')
                content = strip_tags(content).lower()
                content = re.sub(r"[^a-zA-Z0-9]", " ", content)
                feature_files[6].write(content + '\n')
​
                content = json_data['meta_tags']["twitter:description"].replace('\n', ' ').replace('\r', ' ').lower()
                feature_files[7].write(content + '\n')
评论如下:


为什么您认为8次写入会导致8次物理写入硬盘?文件对象本身缓冲要写入的内容,如果它决定写入您的操作系统,您的操作系统可能会等待一段时间,直到它进行物理写入—即使这样,您的驱动器也会有缓冲区,可以将文件内容保留一段时间,直到它真正开始写入。看


您不应该将异常用作控制流,也不应该在不需要异常的地方递归。每个递归都为函数调用准备新的调用堆栈,这需要资源和时间,而且所有调用堆栈都必须还原

最好的做法是在将数据输入json.load()之前清理数据。。。下一个最好的方法是避免递归。。。尝试以下几点:

def read_json_line(line=None):
    result = None

    while result is None and line: # empty line is falsy, avoid endless loop
        try:        
            result = json.loads(line)
        except Exception as e:
            result = None      
            # Find the offending character index:
            idx_to_replace = int(str(e).split(' ')[-1].replace(')',''))      
            # slice away the offending character:
            line = line[:idx_to_replace]+line[idx_to_replace+1:]

     return result

为什么您认为8次写入会导致8次物理写入硬盘?文件对象本身缓冲要写入的内容,如果它决定写入您的操作系统,您的操作系统可能会等待一段时间,直到它进行物理写入-即使这样,您的硬盘驱动器也有缓冲区,可以将文件内容保留一段时间,直到它真正开始写入…谢谢Patrick,我一定会检查它们,还有什么办法可以提高速度吗?我同意你的评论,但写64k行的9分钟时间仍然很慢,其中不超过30个单词(只有一个除外)