2016-09-16 65 views
1

這可能是一個簡單/重複的問題,但我可以找到/找出如何去做。基於密鑰的CSV加入

我有兩個CSV文件中:

info.csv:

"Last Name", First Name, ID, phone, adress, age X [Total age: 100] |009076 

abc, xyz, 1234, 982-128-0000, pqt, 

bcd, uvw, 3124, 813-222-1111, tre, 

poi, ccc, 9087, 123-45607890, weq, 

然後

age.csv:

student_id,age_1 

3124,20 

9087,21 

1234,45 

我想比較兩個csv fi LES,從age.csv和基於列「id」從info.csv和「student_id」採取相應的「age_1」的數據,並把它納入「age」列info.csv

所以最終的輸出應該是:

info.csv:

"Last Name", First Name, ID, phone, adress, age X [Total age: 100] |009076 
abc, xyz, 1234, 982-128-0000, pqt,45 
bcd, uvw, 3124, 813-222-1111, tre,20 
poi, ccc, 9087, 123-45607890, weq,21 

我可以簡單地根據按鍵上的表連接到new.csv,但可不要將數據放在列標題「age」中。我用「csvkit」來做到這一點。

下面是我用什麼:

csvjoin -c 3,1 info.csv age.csv > new.csv 
+0

您可以發佈您的代碼的例子嗎? – alexbclay

回答

1

嘗試......

import csv 

info = list(csv.reader(open("info.csv", 'rb'))) 
age = list(csv.reader(open("age.csv", 'rb'))) 

def copyCSV(age, info, outFileName = 'out.csv'): 
    # put age into dict, indexed by ID 
    # assumes no duplicate entries 

    # 1 - build a dict ageDict to represent data 
    ageDict = dict([(entry[0].replace(' ',''), entry[1]) for entry in age[1:] if entry != []]) 

    # 2 - setup output 
    with open(outFileName, 'wb') as outFile: 
     outwriter = csv.writer(outFile) 
     # 3 - run through info and slot in ages and write to output 
     # nb: had to use .replace(' ','') to strip out whitespaces - these may not be in original .csv 
     outwriter.writerow(info[0]) 
     for entry in info[1:]: 
      if entry != []: 
       key = entry[2].replace(' ','') 
       if key in ageDict: # checks that you have data from age.csv 
        entry[5] = ageDict[key] 
      outwriter.writerow(entry) 

copyCSV(age, info) 

讓我知道,如果它的工作原理,或者如果有不清楚的地方。我使用了一個字典,因爲如果您的文件很大,它應該會更快,因爲您只需循環一次age.csv中的數據即可。

可能有一個更簡單的方法/已經實現的東西......但這應該做的伎倆。

+0

這工作得很好。 – user3285014

+0

好東西!這是我第一個接受的答案! – Aidenhjj

3

您可以使用Pandas並使用age數據更新info dataframe。您可以通過將兩個數據幀的索引分別設置爲IDstudent_id,然後更新info dataframe中的年齡列。之後,您重置索引,以便ID再次成爲列。

from StringIO import StringIO 
import pandas as pd 

info = StringIO("""Last Name,First Name,ID,phone,adress,age X [Total age: 100] |009076 
abc, xyz, 1234, 982-128-0000, pqt, 
bcd, uvw, 3124, 813-222-1111, tre, 
poi, ccc, 9087, 123-45607890, weq,""") 


age = StringIO("""student_id,age_1 
3124,20 
9087,21 
1234,45""") 

info_df = pd.read_csv(info, sep=",", engine='python') 
age_df = pd.read_csv(age, sep=",", engine='python') 

info_df = info_df.set_index('ID') 
age_df = age_df.set_index('student_id') 
info_df['age X [Total age: 100] |009076'].update(age_df.age_1) 
info_df.reset_index(level=0, inplace=True) 
info_df 

輸出:

ID  Last Name First Name  phone   adress age X [Total age: 100] |009076 
0 1234 abc   xyz    982-128-0000 pqt  45 
1 3124 bcd   uvw    813-222-1111 tre  20 
2 9087 poi   ccc    123-45607890 weq  21 
+0

我無法得到這個工作,在我的實際CSV中,最後一個列標題中有空間。這就像「年齡大學生|全部」。 所以,當我用你的代碼的這一行代碼:info_df.age.update(age_df.age_1) 與實際的頭部,它給我語法錯誤。 – user3285014

+0

你介意分享實際的頭文件以及你正在獲得的語法錯誤嗎?有兩件事,你可以重新命名csv文件中的頭文件,或者使用'df.columns'來獲取列名以查看列的實際名稱。 –

+0

這是需要更新的列名稱: u'age X [Total age:100] | 009076' – user3285014