2013-04-28 18 views
15

OK Przeczytałem kilka wątków tutaj na przepełnieniu stosu. Pomyślałem, że byłoby to dla mnie dość łatwe, ale odkryłem, że nadal nie mam dobrego zrozumienia Pythona. Próbowałem przykładu znajdującego się pod adresem How to combine 2 csv files with common column value, but both files have different number of lines i to było pomocne, ale nadal nie mam wyników, które miałem nadzieję osiągnąć.Scalanie 2 plików CSV

Zasadniczo mam 2 pliki CSV ze wspólną pierwszą kolumną. Chciałbym połączyć 2. tj

filea.csv

 
title,stage,jan,feb 
darn,3.001,0.421,0.532 
ok,2.829,1.036,0.751 
three,1.115,1.146,2.921 

fileb.csv

 
title,mar,apr,may,jun, 
darn,0.631,1.321,0.951,1.751 
ok,1.001,0.247,2.456,0.3216 
three,0.285,1.283,0.924,956 

output.csv (nie jeden ja dostaję ale co chcę)

 
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 

output.csv (wyjście że rzeczywiście dostał)

 
title,feb,may 
ok,0.751,2.456 
three,2.921,0.924 
darn,0.532,0.951 

Kod Starałem:

''' 
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]) 

Każda pomoc jest mile widziana.

+0

Czy możesz opisać to, co chcesz w prostszy sposób ?, może mówiąc coś takiego: Chcę, aby kolumny miesiąca zostały scalone, spróbuj kolumny z plikuX – juanpastas

Odpowiedz

1

trzeba przechowywać wszystkie dodatkowych wierszy w plikach w słowniku, a nie tylko jeden z nich:

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

Następnie od wartości w słownikach są listy, trzeba po prostu złączyć wymienia razem:

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

Kiedy pracuję z csv plików, często korzystać z biblioteki pandas. To sprawia, że ​​takie rzeczy są bardzo łatwe. Na przykład:

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) 

Niektóre wyjaśnienie poniżej. Po pierwsze, możemy przeczytać w plikach 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 

i widzimy tam dodatkowa kolumna danych (zauważ, że pierwsza linia fileb.csv - title,mar,apr,may,jun, - ma dodatkowy przecinek na końcu). Możemy pozbyć się, że dość łatwo:

>>> 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 

Teraz możemy połączyć a i b na kolumnie tytuł:

>>> 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 

i wreszcie napisać to uwagę:

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

produkcji:

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 
+0

jak można zrobić .merge na podstawie różnych kolumn nazw? na przykład. jak aTable w kolumnie A scala bTable w kolumnie B. –

+2

@JorgeVidinha: jeśli masz nowe pytanie, proszę otworzyć nowe pytanie - jeśli zadasz to jako komentarz do rocznego pytania, nikt go nie zobaczy. – DSM

+0

Eleganckie rozwiązanie, nawet 4 lata później. Uważaj jednak na metodę '.dropna()', nie używając 'how =" all "; w przeciwnym razie może upuścić kolumny, jeśli DOWOLNE komórki są puste. – WillardSolutions