2015-09-10 104 views
2

我有一個csv文件,csv_file.csv,其中每個狀態有多個記錄,並且狀態用一個id標識。樣本是這樣的:如何將狀態碼從一個csv文件映射到python中另一個csv文件的狀態名稱?

state_id,year,value 
01,2012,8.0 
01,2012,8.1 
01,2012,8.0 
01,2012,7.7 
01,2013,7.3 
01,2013,7.0 
01,2013,7.0 

我想在上面數據集state_id轉換成相應的state_name和記錄寫入到另一個csv文件,output.csv,使每個國家的所有value領域進來一個行和輸出變爲:

Alabama,8.0,8.1,8.0,7.7,7.3,7.0,7.0 
Alaska,8.1,8.1,8.0,7.4,7.25,7.6,7.5 

換做我還有一個csv文件,state.csv映射,與映射的詳細信息:

我寫了這個代碼,但這個似乎只只轉換4條(前4記錄state_id01year2012)的csv_file.csv的,當我打開Output.csv我只看到4條記錄,並且也爲他們的value字段重複。我當前的代碼是:

reader_csv = csv.reader(open('csv_file.csv', 'rb')) 
reader_state = csv.reader(open('states.csv', 'rb')) 
file_write = open('Output.csv', 'a') 
writer = csv.writer(file_write) 

for line in reader_csv: 
    for states in reader_state: 
     if line[0] == states[0]: 
      print line[0]+'='+states[1] 
      writer.writerow([states[1]]+[line[1]]+[line[2]]) 
      break 

file_write.close() 

什麼是我在這裏做了錯誤,我該怎麼做才能改變state_idstate_name映射?

+0

讓我們說,一個國家,從第1行csv_file出現5。你當前的代碼也會讀取第1行到第5行的states_csv(儘管你只希望他讀取states_csv的第1行)。你會「放鬆」4個州。我正在編寫解決方案。 – tomasyany

回答

2

這裏是我的方法:對於state.csv,轉換到這一點查找字典,然後讀取輸入,翻譯,寫:

import csv 

with open('state.csv', 'rb') as f: 
    id2name = dict(csv.reader(f)) 

with open('csv_file.csv', 'rb') as ifile, open('output.', 'wb') as ofile: 
    reader = csv.reader(ifile) 
    writer = csv.writer(ofile) 

    for state_id, year, value in reader: 
     state = id2name[state_id] 
     writer.writerow([state, year, value]) 

更新

更新代碼以將所有值寫入同一行。該解決方案使用itertools.groupby函數,我們按第一個字段對記錄進行分組。輸出不會有標題。

import csv 
from itertools import groupby 

with open('state.csv', 'rb') as f: 
    id2name = dict(csv.reader(f)) 

with open('csv_file.csv', 'rb') as ifile, open('output.csv', 'wb') as ofile: 
    reader = csv.reader(ifile) 
    next(reader) # skip the header 
    writer = csv.writer(ofile) 

    # Group by the state_id, which is the first field (record[0]) 
    group_by_state_id = groupby(reader, lambda record: record[0]) 
    for state_id, record_group in group_by_state_id: 
     state = id2name[state_id] 
     values = [value for state_id, year, value in record_group] 
     writer.writerow([state] + values) 

更新2

如果您的系統已經安裝sqlite3(我的Mac,用它預裝),然後將下面的腳本會得到期望的結果。確保從csv文件中刪除標題。

-- script.sql 

.mode csv 

CREATE TABLE state (sid TEXT, name TEXT); 
.import state.csv state 

CREATE TABLE raw (sid TEXT, year INT, value REAL); 
.import csv_file.csv raw 

SELECT state.name, group_concat(raw.value) 
FROM state, raw 
WHERE state.sid = raw.sid 
GROUP BY state.name; 

要使用它:

$ sqlite3 <script.sql> output.csv 
+0

如果說我想將每個狀態的所有記錄寫入一行,我將如何寫入輸出文件。例如,現在將有12個州的阿拉巴馬州記錄。如果我想將所有值寫入一行,以便輸出文件具有一個阿拉巴馬州的記錄,然後是該州的所有值,該怎麼辦?我也更新了我的帖子。 –

+0

@JasonDonnald是按state_id排序的行嗎? –

+0

yes csv文件中的state_id是按排序順序 –

1

您應該將您的狀態唯一標識符存儲在字典中。然後,訪問csv_file.csv每行的該對象的值。

import csv 

reader_csv = csv.reader(open('csv_file.csv', 'r')) # no b flag for python3 
file_write = open('output.csv', 'a') 
writer = csv.writer(file_write) 

# Dictionary construction 
with open('states.csv', mode='r') as infile: 
    reader = csv.reader(infile) 
    states_dict = {rows[0]:rows[1] for rows in reader} 

# File writing 
for line in reader_csv: 
    writer.writerow([states_dict[line[0]]]+[line[1]]+[line[2]]) 
file_write.close() 
+0

如果說我想將每個狀態的所有記錄寫入一行,我將如何寫入輸出文件。例如,現在將有12個州的阿拉巴馬州記錄。如果我想將所有值寫入一行,以便輸出文件具有一個阿拉巴馬州的記錄,然後是該州的所有值,該怎麼辦?我也更新了我的帖子。 –

+0

那麼,那是另一個問題,然後......我回答了原來的問題。 – tomasyany

+0

我很抱歉改變輸出格式。我沒有意識到,直到根據您的建議對我的代碼進行更新 –

0
import csv 

with open('state.csv') as csvfile: 
    reader = csv.DictReader(csvfile) 
    states = {row.get('state_id'): row.get('state_name') for row in reader} 

with open('csv_file.csv') as csvfile: 
    reader = csv.DictReader(csvfile) 

    with open('output.csv', 'wb') as outfile: 
     fieldnames = ['state_name', 'year', 'value'] 
     writer = csv.DictWriter(outfile, fieldnames=fieldnames) 
     writer.writeheader() 

     for row in reader: 
      writer.writerow({'state_name': states.get(row.get('state_id')), 'year': row.get('year'), 'value': row.get('value')}) 
相關問題