2016-09-16 4 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 ле, на основе столбцов «id» от info.csv и «student_id» от age.csv и принять соответствующие «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) 

Позвольте мне знать, если он работает, или если что-то неясно. Я использовал dict, потому что он должен быть быстрее, если ваши файлы массивны, так как вам нужно только прокручивать данные в age.csv один раз.

Может быть более простой способ/что-то уже реализовано ... но это должно сделать трюк.

+0

Это сработало отлично. – user3285014

+0

Отличный материал! Это мой первый принятый ответ здесь! – Aidenhjj

3

Вы можете использовать Pandas и обновить info dataframe с использованием данных age. Вы делаете это, установив индекс обоих кадров данных на ID и student_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 [Возраст: 100] | 009076 ' – user3285014