Python因处理大文件而中断(杀死)进程如何处理?

问题描述 投票:0回答:1

我有这个小脚本:

import pandas as pd

import os
import glob

novas_colunas = [
    'UF', 'Municipios', 'Área de Ponderação', 'Controle', 'Peso Amostral', 'Região Geográfica', 'Mesorregião', 'Microrregião',
    'Código da Região Metropolitana', 'Situação do Domicilio', 'Espécie de Unidade Visitada','Tipo de Espécie',
    'Condição de Ocupação', 'Valor do Aluguel', 'Aluguel em número de salários', 'Material Predominante', 'Nº de Cômodos',
    'Densidade de Morador', 'Cômodos  com dormitórios', 'Densidade de morador dormitório','Nº de Banheiros', 'Sanitários', 'Tipo de Esgotamento Sanitário', 'Forma de Abastecimento de Água',
    'Canalização', 'Destino do Lixo', 'Existênia de Energia Elétrica',
    'Existência de Medidor de Energia', 'Rádio', 'Televisão', 'Máquina de Lavar',
    'Geladeira', 'Celular', 'Telefone Fixo', 'Microcomputador', 'Microcomputador com internet', 'Motocicleta', 'Automóvel',
    'ALGUMA PESSOA QUE MORAVA COM VOCÊ(S) ESTAVA MORANDO EM OUTRO PAÍS EM 31 DE JULHO DE 2010',
    'QUANTAS PESSOAS MORAVAM NESTE DOMICÍLIO EM 31 DE JULHO DE 2010', 'A RESPONSABILIDADE PELO DOMICÍLIO É DE',
    'DE AGOSTO DE 2009 A JULHO DE 2010, FALECEU ALGUMA PESSOA QUE MORAVA COM VOCÊ(S)',
    'Rendimento Mensal pelo domicilio em Julho de 2010',
    'RENDIMENTO DOMICILIAR, SALÁRIOS MÍNIMOS, EM JULHO DE 2010',
    'RENDIMENTO DOMICILIAR PER CAPITA EM JULHO DE 2010',
    'RENDIMENTO DOMICILIAR PER CAPITA, EM Nº DE SALÁRIOS    MÍNIMOS, EM JULHO DE 2010',
    'Espécie da Unidade Doméstica', 'ADEQUAÇÃO DA MORADIA', 'MARCA DE IMPUTAÇÃO NA V0201:',
    'MARCA DE IMPUTAÇÃO NA V2011:', 'MARCA DE IMPUTAÇÃO NA V0202:', 'MARCA DE IMPUTAÇÃO NA V0203',
    'MARCA DE IMPUTAÇÃO NA V0204', 'MARCA DE IMPUTAÇÃO NA V0205','MARCA DE IMPUTAÇÃO NA V0206',
    'MARCA DE IMPUTAÇÃO NA V0207', 'MARCA DE IMPUTAÇÃO NA V0208', 'MARCA DE IMPUTAÇÃO NA V0209',
    'MARCA DE IMPUTAÇÃO NA V0210', 'MARCA DE IMPUTAÇÃO NA V0211', 'MARCA DE IMPUTAÇÃO NA V0212',
    'MARCA DE IMPUTAÇÃO NA V0213', 'MARCA DE IMPUTAÇÃO NA V0214', 'MARCA DE IMPUTAÇÃO NA V0215',
    'MARCA DE IMPUTAÇÃO NA V0216', 'MARCA DE IMPUTAÇÃO NA V0217', 'MARCA DE IMPUTAÇÃO NA V0218',
    'MARCA DE IMPUTAÇÃO NA V0219', 'MARCA DE IMPUTAÇÃO NA V0220', 'MARCA DE IMPUTAÇÃO NA V0221',
    'MARCA DE IMPUTAÇÃO NA V0222', 'MARCA DE IMPUTAÇÃO NA V0301', 'MARCA DE IMPUTAÇÃO NA V0401',
    'MARCA DE IMPUTAÇÃO NA V0402', 'MARCA DE IMPUTAÇÃO NA V0701', 'SITUAÇÃO DO SETOR']

pasta = 'saida-microdados/*.csv'
arquivos = []
for i in glob.glob(pasta):
  arquivos.append(i)

for i in range(len(arquivos)):
  dataf = pd.read_csv(arquivos[i])
  velhas_colunas = dataf.columns
  dataf.rename(columns = dict(zip(velhas_colunas, novas_colunas)), inplace = 'True')
  dataf.to_csv(arquivos[i])

我想代码本身没问题。问题是这个文件夹中有很多 CSV,其中很多都很大,有很多行。因此,由于我没有生成任何输出,所以我不知道它在哪些文件中更改了列,但是通过访问它们,我发现其中一些已更改,但大多数都没有更改(只有一点点)被改变)。那么,处理这个问题的最佳方法是什么?我尝试过 pypy,但没有解决任何问题。我还将进行列表理解并避免点方法调用。我想我在某处读过,

len(x)
也消耗很多。但这就足够了吗?我想不是。我正在考虑将这些 CSV 文件分为几类,并为每个文件制作一个脚本。我本来期待 pypy 能解决这个问题,但没有。还有另一个脚本,比这个更大(超过 150 行),它读取 txt 文件并生成这些 CSV 文件,但我遇到了同样的问题,该进程在结束之前被终止。

python pandas large-data kill-process
1个回答
0
投票

这是对您的庞大脚本的简单替换。

import fileinput
from glob import glob

novas_colunas = [...]

for filename in glob('saida-microdados/*.csv'):
    firstline = True
    for line in fileinput.input(filename, inplace=True):
        if firstline:
            print(','.join(novas_colunas)
            firstline = False
        else:
            print(line)

这假定标题不包含文字逗号。您可能想要使用

csv
模块进行任何重要的 CSV 处理。

这只是一次读取并忘记一行数据,因此您不应该耗尽内存(除非您的数据包含一些真的长行!)

fileinput
模块负责在后台写入临时文件,并在使用完该文件后通过其
inplace=True
机制替换原始输入文件。

© www.soinside.com 2019 - 2024. All rights reserved.