2016-06-20 9 views
0

入力ファイルのコピー:私は2つのcsvファイル(file1.csvとfile2.csv)を持っているCSVから一致する列が

を。

FILE1は、次のようになります。

name,gender,city,id 

問題:

私はFILE2とFILE1のヘッダを比較してのデータをコピーしたい

ID,Name,Gender 
1,Smith,M 
2,John,M 

FILE2は次のようになります一致する列。 file2の一致する列を見つける前に、file1のヘッダーを小文字にする必要があります。

出力:

は、出力は次のようにする必要があります:

name,gender,city,id # name,gender,and id are the only matching columns btw file1 and file2 
Smith,M, ,1   # the data copied for name, gender, and id columns 
John,M, ,2 

は、私がこれまでに次のコードを試してみました:

import csv 

file1 = csv.DictReader(open("file1.csv")) #reading file1.csv 
file1_Dict = {} # the dictionary of lists that will store the keys and values as list 
for row in file1: 
    for column, value in row.iteritems(): 
     file1_Dict.setdefault(column,[]).append(value) 

for key in file1_Dict: # converting the keys of the dictionary to lowercase 
    file1_Dict[key.lower()] = file1_Dict.pop(key) 

file2 = open("file2.csv") #reading file2.csv 
file2_Dict ={}    # store the keys into a dictionary with empty values 
for row2 in file2: 
    row2 = row2.split(",") 
    for i in row2: 
     file2_Dict[i] = "" 

任意のアイデアどのようにこの問題を解決するために?

答えて

1

私はパフォーマンスを考慮せずにpythonを使用してこの問題に亀裂がありました。かなり長い間、私を受けた!

これは私のソリューションです。

import csv 

csv_data1_filepath = './file1.csv' 
csv_data2_filepath = './file2.csv' 

def main(): 

    # import nem config and data into memory 
    data1 = list(csv.reader(file(csv_data1_filepath, 'r'))) 
    data2 = list(csv.reader(file(csv_data2_filepath, 'r'))) 

    file1_header = data1[0][:] # Get f1 header 
    file2_header = data2[0][:] # Get f1 header 
    lowered_file1_header = [item.lower() for item in file1_header] # lowercase it 
    lowered_file2_header = [item.lower() for item in file2_header] # do it for header 2 anyway 

    col_index_dict = {} 
    for column in lowered_file1_header: 
     if column in file2_header: 
      col_index_dict[column] = lowered_file1_header.index(column) 
     else: 
      col_index_dict[column] = -1 # mark as column that will not be worked on later 

    for column in lowered_file2_header: 
     if not column in lowered_file1_header: 
      col_index_dict[column] = -1 # mark as column that will not be worked on later 

    # build header 
    output = [col_index_dict.keys()] 
    is_header = True 

    for row in data1: 
     if is_header is False: 
      rowData = [] 
      for column in col_index_dict: 
       column_index = col_index_dict[column] 
       if column_index != -1: 
        rowData.append(row[column_index]) 
       else: 
        rowData.append('') 
      output.append(rowData) 
     else: 
      is_header = False 

    print(output) 


if __name__ == '__main__': 
    main() 

これは、あなたの出力与える:出力は一種のその順序を失ったが、これは代わりに注文した辞書を使用して修正可能でなければならないこと

[ 
    ['gender', 'city', 'id', 'name'], 
    ['M', '', '1', 'Smith'], 
    ['M', '', '2', 'John'] 
] 

注意を。

これが役に立ちます。

+0

あなたは素晴らしいです!あなたの努力に感謝します。 – MEhsan

1

これにはPythonは必要ありません。これはSQLのタスクです。

SQLite Browserは、CSVインポートをサポートしています。(のは、テーブル名はそれぞれ、file1とfile2をしているとしましょう)テーブルとして

  • ダウンロードとSQ​​Liteのブラウザ
  • をインストールし、新しいデータベース
  • インポートを作成し、両方のCSVさん:所望の出力を取得するには、以下の手順を実行します。

ここで、データセットの一致方法を決めることができます。

単に最後に
select * 
from file1 f1 
    inner join file2 f2 
    on f1.id = f2.id and f1.name = f2.name and f1.gender = f2.gender 

、:あなたはすべての列に一致させたい場合は、あなたのような何かを行うことができます

select * 
from file1 f1 
    inner join file2 f2 
    on f1.id = f2.id 

:あなたが唯一のID上のファイルを一致させたい場合は、あなたのような何かを行うことができますクエリ結果をCSVにエクスポートし直します。

スクリプト言語でこのようなタスクを実行しようと多くの時間を費やしました。 SQLを使用するメリットは、照合したいものを指定してからデータベースで最適化を実行できることです。一般的に、私は書くことができる任意のコードよりも速くマッチングを行うことになります。

興味がある場合は、pythonにもsqliteモジュールが用意されています。私は、上記の理由でPythonスクリプトのデータソースとしてこれを使用することに重点を置いており、Pythonスクリプトを実行する前にSQLiteブラウザに必要なCSVファイルをインポートするだけです。

+0

銃撃戦にナイフを持ってこないでください。データベース戦闘に辞書を持ってこないでください。 –

+0

@Alex Barry ありがとう!それがそれにアプローチする方法です...しかし、一致する列がたくさんある場合はどうなりますか? select文でそれらを結合する頭痛にならないでしょうか? – MEhsan

+0

はい、そうかもしれませんが、私は全体のスクリプトを書くよりも頭痛が少ないと思うでしょう:)。あなたが本当に心配している場合は、CSV /テーブルヘッダに基づいてSQL文を生成するPythonスクリプトを書くことができます。そして、sqliteモジュールを使ってSQL文を実行してください。 –

関連する問題