列の入れ替え
今回も小ネタ。個人的に少々苦労したので記録。CSVファイルの列の入れ替えである。エクセルやpandasライブラリ簡単にできそうなのであるが、辞書を使って、自身のコードで明示的に入れ替えたいなどの理由から実施。
ソースコード
サンプルCSV
実際には30列以上あるものを対象としていたが、ここでは簡単なサンプルとして下記のようなものを対象とする。まず、データは下記の順番で記載されている、、、という前提がある。
id,family,name,age,nationality
実際のCSVファイルはこちら。
sample.csv
2,Tanaka,Koh,45,Japan
4,Jon,Andersson,64,Sweden
7,Emily,Wang,34,Taiwan
下記がソースコード。コメントも含めている。
column.csv
# -*- coding: utf-8 -*-
import csv
# 列番号用辞書:数値が列番号、この数値を書き換えることにより、列の入れ替えを実施
dic = {'id':2, 'family':3, 'name':5, 'age':4, 'nationality':1}
# データ一時格納用辞書
data = {'id':'', 'family':'', 'name':'', 'age':'', 'nationality':''}
# 列番号でソート
sorted = sorted(dic.items(), key=lambda x:x[1]) # tuple
print(sorted)
# タプルを辞書化
dic_sorted = {k: v for k, v in sorted} # to dictionaly
print(dic_sorted)
# ソートされた列のヘッダを取得
list_sorted = [k for k, v in sorted]
print(list_sorted)
# 対象ファイル読み込み
r_file = open('sample.csv', 'r')
r_data = csv.reader(r_file)
# 書き込みファイル
w_file = open('output.csv', 'w', newline='')
writer = csv.writer(w_file)
# ヘッダ書き込み
writer.writerow(list_sorted)
# 読み込みデータを1行ずつ処理
for row in r_data:
# データを辞書に登録
data['id'] = row[0]
data['family'] = row[1]
data['name'] = row[2]
data['age'] = row[3]
data['nationality'] = row[4]
# 辞書をリスト化
write_list = [data[i] for i in list_sorted]
#print(write_list)
# データ書き込み
writer.writerow(write_list)
# ファイルクローズ
r_file.close()
w_file.close()
テスト
実行。
$ python3 column.py
[('nationality', 1), ('id', 2), ('family', 3), ('age', 4), ('name', 5)]
{'nationality': 1, 'id': 2, 'family': 3, 'age': 4, 'name': 5}
['nationality', 'id', 'family', 'age', 'name']
結果ファイルは下記となる。
output.csv
nationality,id,family,age,name
Japan,2,Tanaka,45,Koh
Sweden,4,Jon,64,Andersson
Taiwan,7,Emily,34,Wang
次に、ソースコードを下記のように書き換える。
dic = {'id':1, 'family':3, 'name':2, 'age':5, 'nationality':4}
この時の結果ファイルは下記となる。
output.csv
id,name,family,nationality,age
2,Koh,Tanaka,Japan,45
4,Andersson,Jon,Sweden,64
7,Wang,Emily,Taiwan,34