web-dev-qa-db-fra.com

Fusion de deux fichiers CSV en utilisant Python

OK, j'ai lu plusieurs discussions ici sur Stack Overflow. Je pensais que ce serait assez facile pour moi, mais je trouve que je n'ai toujours pas une très bonne compréhension de Python. J'ai essayé l'exemple situé à Comment combiner 2 fichiers csv avec une valeur de colonne commune, mais les deux fichiers ont un nombre de lignes différent et c'était utile mais je n'ai toujours pas les résultats que j'espérais atteindre .

Essentiellement, j'ai 2 fichiers csv avec une première colonne commune. Je voudrais fusionner le 2. i.e.

filea.csv

 titre, étape, jan, fév 
 darn, 3.001,0.421,0.532 
 ok, 2.829,1.036,0.751 
 trois, 1.115,1.146,2.921 

fileb.csv

 titre, mars, avril, mai, juin, 
 darn, 0.631,1.321,0.951,1.751 
 ok, 1.001,0.247,2.456,0.3216 
 trois, 0,285,1,283,0,924,956 

output.csv (pas celui que j'obtiens mais ce que je veux)

 titre, étape, jan, feb, mar, apr, mai, jun 
 darn, 3.001,0.421,0.532,0.631,1.321,0.951,1.751 
 ok, 2.829,1.036 , 0,751,1.001,0.247,2.456,0.3216 
 Trois, 1.115,1.146,2.921,0.285,1.283,0.924,956 

output.csv (la sortie que j'ai réellement obtenue)

 titre, fév, mai 
 ok, 0,751,2,456 
 trois, 2,921,0,924 
 darn, 0,532,0,951 

Le code que j'essayais:

'''
testing merging of 2 csv files
'''
import csv
import array
import os

with open('Z:\\Desktop\\test\\filea.csv') as f:
    r = csv.reader(f, delimiter=',')
    dict1 = {row[0]: row[3] for row in r}

with open('Z:\\Desktop\\test\\fileb.csv') as f:
    r = csv.reader(f, delimiter=',')
    #dict2 = {row[0]: row[3] for row in r}
    dict2 = {row[0:3] for row in r}

print str(dict1)
print str(dict2)

keys = set(dict1.keys() + dict2.keys())
with open('Z:\\Desktop\\test\\output.csv', 'wb') as f:
    w = csv.writer(f, delimiter=',')
    w.writerows([[key, dict1.get(key, "''"), dict2.get(key, "''")] for key in keys])

Toute aide est grandement appréciée.

20
Rex

Lorsque je travaille avec des fichiers csv, j'utilise souvent la bibliothèque pandas . Cela rend les choses comme ça très faciles. Par exemple:

import pandas as pd

a = pd.read_csv("filea.csv")
b = pd.read_csv("fileb.csv")
b = b.dropna(axis=1)
merged = a.merge(b, on='title')
merged.to_csv("output.csv", index=False)

Une explication suit. Tout d'abord, nous lisons dans les fichiers csv:

>>> a = pd.read_csv("filea.csv")
>>> b = pd.read_csv("fileb.csv")
>>> a
   title  stage    jan    feb
0   darn  3.001  0.421  0.532
1     ok  2.829  1.036  0.751
2  three  1.115  1.146  2.921
>>> b
   title    mar    apr    may       jun  Unnamed: 5
0   darn  0.631  1.321  0.951    1.7510         NaN
1     ok  1.001  0.247  2.456    0.3216         NaN
2  three  0.285  1.283  0.924  956.0000         NaN

et nous voyons qu'il y a une colonne supplémentaire de données (notez que la première ligne de fileb.csv - title,mar,apr,may,jun, - a une virgule supplémentaire à la fin). Nous pouvons nous en débarrasser assez facilement:

>>> b = b.dropna(axis=1)
>>> b
   title    mar    apr    may       jun
0   darn  0.631  1.321  0.951    1.7510
1     ok  1.001  0.247  2.456    0.3216
2  three  0.285  1.283  0.924  956.0000

Maintenant, nous pouvons fusionner a et b sur la colonne de titre:

>>> merged = a.merge(b, on='title')
>>> merged
   title  stage    jan    feb    mar    apr    may       jun
0   darn  3.001  0.421  0.532  0.631  1.321  0.951    1.7510
1     ok  2.829  1.036  0.751  1.001  0.247  2.456    0.3216
2  three  1.115  1.146  2.921  0.285  1.283  0.924  956.0000

et enfin écrire ceci:

>>> merged.to_csv("output.csv", index=False)

produisant:

title,stage,jan,feb,mar,apr,may,jun
darn,3.001,0.421,0.532,0.631,1.321,0.951,1.751
ok,2.829,1.036,0.751,1.001,0.247,2.456,0.3216
three,1.115,1.146,2.921,0.285,1.283,0.924,956.0
60
DSM

Vous devez stocker toutes les lignes supplémentaires dans les fichiers de votre dictionnaire, pas seulement l'une d'entre elles:

dict1 = {row[0]: row[1:] for row in r}
...
dict2 = {row[0]: row[1:] for row in r}

Puis, comme les valeurs dans les dictionnaires sont des listes, vous devez simplement concaténer les listes ensemble:

w.writerows([[key] + dict1.get(key, []) + dict2.get(key, []) for key in keys])
1
Xymostech