2017-05-16 147 views
0

我有一个CSV文件看起来或多或少是这样的:转换某些列到字典蟒蛇

STUDENT_SUBJECT_AREA_VALUE | STUDENT_LEVEL | HOST_INSTITUTION 

222       1    UK 

58       1    PT 

222       1    FR 

223       1    UK 

222       1    PT 

我需要做的是从“HOST_INSTITUTION”列采取的价值观和指望有多少次呢该值出现。输出应该是这样的字典:

{UK: 2, PT: 2, FR: 1} 

我试图转换CSV文件导入字典,但该文件是非常非常大的,我只需要一个特定的列。有没有办法通过CSV并只阅读我需要的专栏? 我转换CSV文件到这样一个字典:

def csv_to_dict(file_name): 
    with open(file_name, 'rU') as file: 
     reader = csv.DictReader(file, delimiter=',') 
     return [line for line in reader] 

可是这样一来,我经历的所有列unnecessarilly。如果我不清楚,请随时提出任何问题。

回答

0

除非它确实是一个性能瓶颈,否则您可能需要逐行读取所有列到内存中。与您的解决方案不同,这不会将整个CSV保留在内存中,而只是计数。

def csv_to_dict(file_name): 
    cnt = Counter() 
    with open(file_name, 'rU') as file: 
     reader = csv.reader(f, delimiter=',') 
     for row in reader: 
      host_inst = row[2] 
      cnt[host_inst] +=1 
    return cnt 

>>> csv_to_dict("my_file.txt") 
Counter({'UK':2,"PT":2,"FR":1}) 
+0

不幸的是,我在得到一个列表索引超出范围的错误“键=行[2]” – Stagg

+0

@Stagg您的CSV可能不是结构良好。你能粘贴它的前10行吗? – gidim

+0

CSV非常长,我从这里下载了它:http://data.europa.eu/euodp/data/dataset/erasmus-mobility-statistics-2012-13。这是'伊拉兹马斯学生流动的原始数据(2012-13学习交流和工作实习)'。 – Stagg

0

为了增强性能,您可能需要尝试一下熊猫。 例如:

import pandas as pd 
d = pd.read_csv("bla.txt") 
d.groupby("HOST_INSTITUTION").count(["STUDENT_SUBJECT_AREA_VALUE"].to_dict() 

会产生期望的结果:)

{'UK': 2, 'FR': 1, 'PT': 2} 
1

壳方式:awk '{print $3}' csv_file_path | sort | uniq -c

您的CSV文件delimitered多的空间。

如果你不想使用计数器:

def csv_to_dict(file_name): 
    result = {} 
    with open(file_name, 'r') as file: 
     reader = csv.reader(file, delimiter=' ', skipinitialspace=True) 
     for row in reader: 
      key = row[2] 
      value = result.get(key, 0) + 1 
      result[key] = value 
    return result 

dict.get(key, default_value),如果键不存在,它会返回DEFAULT_VALUE

In [25]: csv_to_dict(your_file_path) 
Out[25]: {'FR': 1, 'PT': 2, 'UK': 2} 

我的CSV文件内容:

STUDENT_SUBJECT_AREA_VALUE | STUDENT_LEVEL | HOST_INSTITUTION 
222       1    UK 
58       1    PT 
222       1    FR 
223       1    UK 
222       1    PT 
+0

不幸的是,我得到一个列表索引超出范围内的错误“key = row [2]” – Stagg

+0

@Stagg对不起,我的错误。您的csv文件由多个空格分隔。这不是完美的csv格式。等一下 – wwulfric

+0

没问题,谢谢你的帮助:) – Stagg

0

data.csv作为您的输入文件

STUDENT_SUBJECT_AREA_VALUE | STUDENT_LEVEL | HOST_INSTITUTION 

222       1    UK 

58       1    PT 

222       1    FR 

223       1    UK 

222       1    PT 

您可以使用csv.DictReader()读你的CSV与dict 掌握这些信息之后,就可以使用itemgetteroperator模块把所有的值与键名HOST_INSTITUTION

import csv 
def csv_to_dict(file_name='data.csv'): 
    result = {} 
    with open(file_name, 'r') as file: 
     reader = csv.DictReader(file, delimiter=' ', skipinitialspace=True,fieldnames=('STUDENT_SUBJECT_AREA_VALUE','STUDENT_LEVEL','HOST_INSTITUTION')) 
     from operator import itemgetter 
     res = map(itemgetter('HOST_INSTITUTION'),reader)[1:] #this will print ['UK', 'PT', 'FR', 'UK', 'PT'] 
     return {each:res.count(each)for each in set(res)} 
print csv_to_dict() 

输出

{'FR': 1, 'UK': 2, 'PT': 2}