Cria uma tabela com a frequência de nomes exclusivos recuperados de vários arquivos .csv

3

Eu tenho 32 arquivos CSV contendo informações obtidas de um banco de dados. Eu preciso fazer uma tabela de freqüência no formato TSV / CSV, onde os nomes das linhas são o nome de cada arquivo, e os nomes das colunas são os nomes exclusivos encontrados em todos os arquivos. A tabela precisa ser preenchida com a contagem de frequência de cada nome para cada arquivo. O maior problema é que nem todos os arquivos contêm os mesmos nomes buscados.

.csv input:

$cat file_1

name_of_sequence,C cc,'other_information'
name_of_sequence,C cc,'other_information'
name_of_sequence,C cc,'other_information'
name_of_sequence,D dd,'other_information'
...

$cat file_2

name_of_sequence,B bb,'other_information'
name_of_sequence,C cc,'other_information'
name_of_sequence,C cc,'other_information'
name_of_sequence,C cc,'other_information'
...

$cat file_3

name_of_sequence,A aa,'other_information'
name_of_sequence,A aa,'other_information'
name_of_sequence,A aa,'other_information'
name_of_sequence,A aa,'other_information'
...

$cat '.csv/.tsv' output:

taxa,A aa,B bb,C cc,D dd    
File_1,0,0,3,1    
File_2,0,1,3,0    
File_3,4,0,0,0    

Usando o bash, sei como cut a segunda coluna, sort e uniq os nomes e, em seguida, obtenho uma contagem para cada nome em cada arquivo. Eu não sei como fazer uma tabela que mostrará todos os nomes, contagens e coloque um "0 quando o nome não existir no arquivo". Eu normalmente classifico dados com o Bash, mas um script python também funciona.

    
por Lucia O 29.04.2016 / 16:40

1 resposta

1

O seguinte deve funcionar com o python 2 e 3, salvar como xyz.py e executar com% python xyz.py file_1 file_2 file_3 :

import sys
import csv

names = set()  # to keep track of all sequence names

files = {}  # map of file_name to dict of sequence_names mapped to counts
# counting
for file_name in sys.argv[1:]:
    # lookup the file_name create a new dict if not in the files dict
    b = files.setdefault(file_name, {})    
    with open(file_name) as fp:
        for line in fp:
            x = line.strip().split()  # split the line 
            names.add(x[1])  # might be a new sequence name
            # retrieve the sequence name or set it if not there yet
            # what would not work is "i += 1" as you would need to assign
            # that to b[x[1]] again. The list "[0]" however is a reference 
            b.setdefault(x[1], [0])[0] += 1  

# output
names = sorted(list(names))  # sort the unique sequence names for the columns
grid = []
# create top line
top_line = ['taxa']
grid.append(top_line)
for name in names:
    top_line.append(name)
# append each files values to the grid
for file_name in sys.argv[1:]:
    data = files[file_name]
    line = [file_name]
    grid.append(line)
    for name in names:
        line.append(data.get(name, [0])[0])  # 0 if sequence name not in file
# dump the grid to CSV
with open('out.csv', 'w') as fp:
    writer = csv.writer(fp)
    writer.writerows(grid)

Usar [0] para os contadores facilita a atualização do valor do que usar inteiros diretamente. Se os arquivos de entrada forem mais complexos, é melhor lê-los com a biblioteca CSV do Python

    
por 29.04.2016 / 17:46