2013-05-29 191 views
1

我有一个.csv文件如下(片段)。Python:比较一个列表的索引到另一个,追加第二个列表值到第一个列表

Country,Year,GDP ($US),Population 
Angola,2002,11431738368,10760510 
Angola,2005,32810672128,11706954 
Antigua and Barbuda,2002,714677760,67448 
Antigua and Barbuda,2005,875751360,68722 
Argentina,2002,1.02E+11,38331121 
Argentina,2005,1.83E+11,39537943 
Armenia,2002,2376335104,3013818 
Armenia,2005,4902779392,2982904 
... 

我需要找到五个最低GDP /流行国家的2002,然后找到其2005年国内生产总值相应/流行值,然后计算的差异和百分比差异。某些记录有GDP或人口值的空白,我省略。

到目前为止,我用

import csv 
import operator 

data = open('file.csv') 
read_data = csv.reader(data) 

thisthing = [] 
for line in read_data: 
#find 2002 GDP/Pop, omit blanks, append to list 
    if line[7] == '2002' and line[8] != ' ' and line[9] != ' ': 
     thisthing.append([line[0], (float(line[8])/(int(line[9])))]) 

thisthing.sort(key=operator.itemgetter(1)) 

这样就产生了通过线打印线如下列表(国家,GDP/POP):

['Burma (Myanmar)', 69.07171351277908] 
['Burundi', 89.45864552423431] 
['Congo (Dem. Rep.)', 99.23033109735835] 
['Ethiopia', 109.33326343550823] 
['Eritrea', 142.8576737907048] 
['Guinea-Bissau', 151.110429668747] 
['Afghanistan', 159.7524117568956] 
['Malawi', 159.7614709537829] 
['Sierra Leone', 174.6506490278577] 

我想现在通过“的read_data迭代回',在'thisthing'中使用国家名称作为条件以及我的空白预防条件

and line[8] != ' ' and line[9] != ' ': 

选择并附加2005年的国内生产总值/流行音乐'thisthing'

我不知道从哪里开始这样做,我一直在这里呆了一周左右...任何帮助将不胜感激。

+0

您的指数看起来很奇怪。索引2至6的列在哪里? '国家'是0,但'年'是7. –

+0

嗨迈克,这是一个编辑文件。这些索引都是他们应该为完整文件所做的。 – Rookierookie

+0

最好把你的问题归结为真正有用的东西。 这有助于开发一个真正做你想要的解决方案。 –

回答

0

以此为read_data

[['Country', 'Year', 'GDP ($US)', 'Population'], 
['Angola', '2002', '11431738368', '10760510'], 
['Angola', '2005', '32810672128', '11706954'], 
['Antigua and Barbuda', '2002', '714677760', '67448'], 
['Antigua and Barbuda', '2005', '875751360', '68722'], 
['Argentina', '2002', '1.02E+11', '38331121'], 
['Argentina', '2005', '1.83E+11', '39537943'], 
['Armenia', '2002', '2376335104', '3013818'], 
['Armenia', '2005', '4902779392', '2982904']] 

我们不希望第一行:

read_data = read_data[1:] 

如果使用csv.read对象read_data做:

next(read_data) 

实际上,代码足够健壮,可遍历所有行 ,因为我们跳过了由于将字符串 转换为不起作用的数字而导致例外的行,即'GDP ($US)''Population'。 但是,显示我们打算跳过第一行仍然是一个好习惯。 因为我们都知道:显式比隐式更好。

我们使用defaultdict以避免在一年中的第一次插入测试:

import collections 
data = collections.defaultdict(dict) 

for line in read_data: 
    try: 
     gdp = float(line[2])/float(line[3]) 
    # Make sure this exception catches what you want. 
    except (ValueError, ZeroDivisionError): 
     continue 
    data[line[0]][line[1]] = gdp 

现在,我们得到这样的data

{'Angola': {'2002': 1062.3788619684383, '2005': 2802.6651619200006}, 
'Antigua and Barbuda': {'2002': 10595.981496856837, 
         '2005': 12743.391635866245}, 
'Argentina': {'2002': 2661.023140961622, '2005': 4628.465370593508}, 
'Armenia': {'2002': 788.4799626254804, '2005': 1643.6262756025671}} 

我们需要重新安排到你列表:

list_data = [] 
for key, value in data.items(): 
    list_data.append([key] + [value[year] for year in sorted(value.keys())]) 

结果:

[['Antigua and Barbuda', 10595.981496856837, 12743.391635866245], 
['Argentina', 2661.023140961622, 4628.465370593508], 
['Angola', 1062.3788619684383, 2802.6651619200006], 
['Armenia', 788.4799626254804, 1643.6262756025671]] 

此解决方案适用于任何年份并将它们按时间顺序排列。

编辑

事实证明,该数据包含了两年多。我不想整年。更改最后一节只包括要明确的岁月:

list_data = [] 
for key, value in data.items(): 
    list_data.append([key] + [value[year] for year in ('2002', '2005')]) 

EDIT2

小的修改,如果今年是缺少由OP的要求:

list_data = [] 
for key, value in data.items(): 
    list_data.append([key] + [value.get(year, 0) for year in ('2002', '2005')]) 

这使得在0如果一年失踪。使用任何合适的其他值来指示缺失值。

EDIT3

由OP请求另一种变型。如果没有值,则不追加:

list_data = [] 
for key, value in data.items(): 
    list_data.append([key] + [value.get(year) for year in ('2002', '2005') 
           if value.get(year) is not None]) 
+0

谢谢!为'在线read_data [1:]:'我得到'TypeError:'文件'对象没有属性'__getitem __'' – Rookierookie

+0

是的我使用列表,但你使用' csv.reader'实例,然后'next(read_data)'',然后遍历'read_data'而不需要'[:1]',我将更新答案 –

+0

感谢您的帮助Mike。我认为在使用编辑文件这让你更加困惑,这会返回结果,但它也会返回每个国内生产总值年......有更多的年份比2002年和2005年... – Rookierookie

0

试试这个!

import csv 
import operator 

data = open('file.csv') read_data = csv.reader(data) 

data_2002 = {} 
data_2005 = {} 

thisthing = [["country", "2002%", "2005%"]] 

for line in read_data: 
    try: 
     gdp = float(line[8])/(int(line[9])) 
     if line[7] == '2002' and line[8] != ' ' and line[9] != ' ': 
      data_2002[line[0]] = gdp 

     elif line[7] == '2005' and line[8] != ' ' and line[9] != ' ': 
      data_2002[line[0]] = gdp 
    except KeyError: 
     print line[0] 
     continue 

for country in data_2002: 
    thisthing.append([country, data_2002[country], data_2005[country]]) 

print thisthing 
+0

@ abhishekgarg'Canada,2002,7.24E + 11,31902268' 'Canada,2005,1.11E + 12,32805041' – Rookierookie

+0

@abishekgarg 谢谢!我把它插在买了'KeyError:'加拿大'':( – Rookierookie

+0

什么是你的csv 2002和2005的加拿大值 – abhishekgarg

相关问题