2015-09-10 62 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')}) 
相关问题