Dividindo um CSV de 7 milhões de linhas por uma coluna específica

2

Como eu poderia dividir um arquivo CSV muito grande (7 milhões de linhas) em várias folhas / arquivos diferentes por uma coluna numérica específica? Ele deve ser dividido em aproximadamente 10 arquivos diferentes.

    
por BrandonMXB 02.06.2014 / 02:07

3 respostas

3

Use este programa Python 3 :

#!/usr/bin/env python3
import binascii
import csv
import os.path
import sys
from tkinter.filedialog import askopenfilename, askdirectory
from tkinter.simpledialog import askinteger

def split_csv_file(f, dst_dir, keyfunc):
    csv_reader = csv.reader(f)
    csv_writers = {}
    for row in csv_reader:
        k = keyfunc(row)
        if k not in csv_writers:
            csv_writers[k] = csv.writer(open(os.path.join(dst_dir, k),
                                             mode='w', newline=''))
        csv_writers[k].writerow(row)

def get_args_from_cli():
    input_filename = sys.argv[1]
    column = int(sys.argv[2])
    dst_dir = sys.argv[3]
    return (input_filename, column, dst_dir)

def get_args_from_gui():
    input_filename = askopenfilename(
        filetypes=(('CSV', '.csv'),),
        title='Select CSV Input File')
    column = askinteger('Choose Table Column', 'Table column')
    dst_dir = askdirectory(title='Select Destination Directory')
    return (input_filename, column, dst_dir)

if __name__ == '__main__':
    if len(sys.argv) == 1:
        input_filename, column, dst_dir = get_args_from_gui()
    elif len(sys.argv) == 4:
        input_filename, column, dst_dir = get_args_from_cli()
    else:
        raise Exception("Invalid number of arguments")
    with open(input_filename, mode='r', newline='') as f:
        split_csv_file(f, dst_dir, lambda r: r[column-1]+'.csv')
        # if the column has funky values resulting in invalid filenames
        # replace the line from above with:
        # split_csv_file(f, dst_dir, lambda r: binascii.b2a_hex(r[column-1].encode('utf-8')).decode('utf-8')+'.csv')

Salve-o como split-csv.py e execute-o no Explorer ou na linha de comando.

Por exemplo, para dividir superuser.csv com base na coluna 1 e gravar os arquivos de saída em dstdir use:

python split-csv.py superuser.csv 1 dstdir

Se você executá-lo sem argumentos, uma GUI baseada em Tkinter solicitará que você escolha o arquivo de entrada, a coluna (índice baseado em 1) e o diretório de destino.

    
por 02.06.2014 / 03:21
4

Isso pode ser tão simples quanto este one-liner com awk :

awk -F ',' '{ print > ("split-" $1 ".csv") }' 7mil.csv
  • O arquivo de entrada aqui é 7mil.csv
  • O número da coluna decisiva é indicado com o cifrão. Se fosse a terceira coluna, seria $3 em vez de $1
  • O valor da coluna é usado para gerar o nome do arquivo resultante. Por exemplo, cada linha com o valor 42 estará em um arquivo chamado split-42.csv
  • O separador de campo é a vírgula
    • que funciona porque / se o valor é numérico e não possui aspas que precisam ser removidas
    • , mas também requer que não haja vírgulas em nenhuma string no arquivo (pelo menos não antes da coluna numérica)

Então, isso apenas lê todas as linhas e as imprime no arquivo que corresponde ao valor. Observe que ele é adicionado ao arquivo, portanto, se você executá-lo duas vezes, todos os dados serão duplicados; Portanto, certifique-se de que não haja arquivos com esse padrão de nomenclatura para iniciar: del split-*.cvs

O difícil é tentar instalar o awk no Windows. Há o gawk para Windows e um algumas dicas para executá-lo aqui .

    
por 02.06.2014 / 03:23
1

Delimitar pode fazer isso. Ele abre arquivos csv grandes muito rápidos ("até 2 bilhões de linhas e 2 milhões de colunas grandes!"). Use a divisão verticalmente e / ou escolha suas colunas.

Outro software que pode ser capaz de fazê-lo é Emeditor .

    
por 23.07.2014 / 18:48

Tags