(発展:)Python CSVを扱う時のリストと辞書を研究する
1.読み込み
csvモジュールをインポートします。
import csv
◆-- !! List !! --◆
=======================================
◆ List型のCSVを書き込む
=======================================
◆simpleなリスト形式
openの第二引数: 'w ' : 書き込み
import csv
sample=['name','Freddie', 'song', 'Rock you', 'year', '1977']
with open ('a.csv','w', newline='') as f:
mySample = csv.writer(f, delimiter=",")
mySample.writerow (sample)
print(mySample) #<_csv.writer object at 0x0000000002EEAC50>
sample=['name','Freddie', 'song', 'Rock you', 'year', '1977']
with open ('a.csv','w', newline='') as f:
mySample = csv.writer(f, delimiter=",")
mySample.writerow (sample)
print(mySample) #<_csv.writer object at 0x0000000002EEAC50>
これを実行すると、実行ファイルと同じディレクトリに、以下のような a という名前のcsvファイルが作成される。事前に a というcsvファイルを作成しておく必要はない。
print(mySample) の実行結果は、#<_csv.writer object at 0x0000000002EEAC50> として、コンソールに表示されます。
◆List内にListを内包する形式
上記の例では、シンプルなリストを最初に定義しておきましたが、個別に 'row' 毎に記述して書き込むことも可能。
import csv
with open ('a.csv','w', newline='') as f:
writer = csv.writer(f, delimiter=",")
writer.writerow (['name','Freddie'])
writer.writerow (['song','Rock you'])
writer.writerow (['year','1977'])
実行すると、前回と同様に、a という.csvファイルが作成され、こんな感じのデータが書き込まれます。
name age
Freddie 24
title year
Bohemian Rhapsody 1974
(2)作成したCSVを以下のコードで1行ずつ再度、読みだす。
(コード:)
import csv
with open("a.csv","r") as f:
reader=csv.reader(f)
for line in reader:
print(line)
(Output)
['name', 'age']
['Freddie', '24']
['title', 'year']
['Bohemian Rhapsody', '1974']
(コード:要素を指定して1行ずつ)
import csv
with open("a.csv","r") as f:
reader=csv.reader(f)
for line in reader:
print(line[0])
(Output)
name
Freddie
title
Bohemian Rhapsody
(3) 読み込んだリストを新しいリストに格納してからprint
list()関数の使用
import csv
with open("a.csv","r") as f:
reader=csv.reader(f)
data=list(reader)
print(data)
(Output) リストを内包するリストが作られる。
[['name', 'age'], ['Freddie', '24'], ['title', 'year'], ['Bohemian Rhapsody', '1974']]
(4)辞書型に変換する(*これは大事なので後で詳述予定。)
*dict関数を使用
data=dict(reader)
print(data)
(Output) 辞書が作られる。
{'name': 'age', 'Freddie': '24', 'title': 'year', 'Bohemian Rhapsody': '1974'}
with文なしで
import csvf = open('sample.csv', 'w')
writer = csv.writer(f, linetermination='\n')
writer.writerow(list)
writer.writerows(array2d)
f.close() #開いたら忘れず閉じる。
例) test1.csvのデータ(value)をtest2.csvに書き込む
開いたcsvのデータを、別のcsvに書き込む。
readerメソッド)
import csv
with open("test1.csv","r") as csv_file:
csv_reader = csv.reader(csv_file)
with open("test2.csv", "w") as new_file: <-ファイルが無ければ作成してくれる。
csv_writer = csv.writer(new_file, delimiter='\t') #writerメソッド。delimiterは区切りを変更したければ。
for line in csv_reader: <-csv_readerはイテラブル。writerは違う。 あたりまえだけど
csv_writer.writerow(line)
*Listを1行、追加したい場合は、for文の代わりに、csv_writer.writerow(リスト名)を書けば良い。
=======================================
◆ List型のCSVを読み込む
=======================================
with文ありで
import csv
with open("start.csv","r", encoding='utf-8_sig') as f: #windows encoding用の記述
reader = csv.reader(f) #左のreaderは、variableで名前はなんでも良い。 csv.readerはmethod
#この段階でprint(reader)とすると、読み込まれたレジストリの位置情報が格納されている。
#この段階でreaderに格納されている値を確認したい場合、pirnt(list(reader))で表示できる。
for line in reader:
print(line)
print(line[2])
with open("start.csv","r", encoding='utf-8_sig') as f: #windows encoding用の記述
reader = csv.reader(f) #左のreaderは、variableで名前はなんでも良い。 csv.readerはmethod
#この段階でprint(reader)とすると、読み込まれたレジストリの位置情報が格納されている。
#この段階でreaderに格納されている値を確認したい場合、pirnt(list(reader))で表示できる。
for line in reader:
print(line)
print(line[2])
openの第二引数:
r : 読み込み
==readerメソッドとDictReaderメソッド
reader = csv.reader(f)の代わりに
reader = csv.DictReader(f) とすると、1行目がkeyとして扱われる、
openで使えるオプション
newline="" :改行の自動処理
==read
これはイテレータです。
イテレータとは、「イテレータ(英語: Iterator)とは、プログラミング言語において配列やそれに類似するデータ構造の各要素に対する繰返し処理の抽象化である。」と書いてありますが、要は、For 文とかで一つずつ取り出さないと、値が読めないデータの塊りのようです。
但し、ここで読み込んだcsvの値をイテレータのまま、Jinjaに渡そうとすると、以下のようなエラーメッセジがでる。
pyファイル:
from flask import Flask, render_template
import csv
app = Flask(__name__)
@app.route('/')
def home():
with open("sampleTest.csv","r", encoding='utf-8_sig') as f:
reader = csv.reader(f)
return render_template("sample01.html", passMessage=reader)
if __name__ == '__main__':
app.run()
DOSのエラーメッセージ:
-level template code
{% for post in passMessage %}
ValueError: I/O operation on closed file.
読み込んだ値をそのまま、別のファイルに渡すのは無理みたい。
そこで、リストに格納して、データを渡せるようにする。
記事: Python3 CSVを読み込んでリストに格納。 -イテレータの取り扱い
例)
import csv
# ファイルを読み込みモードでオープン
with open('sample.csv', 'r') as f: # withでファイルを開くとファイルcloseの為の記述不要。
reader = csv.reader(f) # readerオブジェクトを作成
header = next(reader) # 最初の一行をヘッダーとして取得。単にnext(reader)としても良い。
print ''.join(header) # ヘッダーをスペース区切りで表示
# 行ごとのリストを処理する
for row in reader:
print ''.join(row) # 1行ずつスペース区切りで表示
word = "Good morning, Hello, Good night"
words = word.split(',')
with open('start.csv', 'w') as f:
writer = csv.writer(f)
# ファイルを読み込みモードでオープン
with open('sample.csv', 'r') as f: # withでファイルを開くとファイルcloseの為の記述不要。
reader = csv.reader(f) # readerオブジェクトを作成
header = next(reader) # 最初の一行をヘッダーとして取得。単にnext(reader)としても良い。
print ''.join(header) # ヘッダーをスペース区切りで表示
# 行ごとのリストを処理する
for row in reader:
print ''.join(row) # 1行ずつスペース区切りで表示
word = "Good morning, Hello, Good night"
words = word.split(',')
with open('start.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow
*next(reader)を2回書くと、上から2行がスキップされる。
reader = csv.reader(f) # readerオブジェクトを作成
next(reader)
next(reader)
*csvで、値を区切るものをdelimeterと言いますが、これがあると読みにくかったりします。
◆-- !! Dictionary !! --◆
=======================================
◆ Dictionary型のCSVを書き込む
=======================================
DictReaderメソッド)
*空のcsv.fileをPython Appと同じディレクトリー内につくる。
test.py
import csv
with open('test.csv', 'w') as csv_file:
fieldnames = ['Date','Name', 'Score']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames,lineterminator='\n')
writer.writeheader()
writer.writerow({'Date':'0117',''Name': 'Mike', 'Score': 90})
writer.writerow({'Date':'0317', 'Name': 'Bob', 'Score': 95})
with open('test.csv', 'w') as csv_file:
fieldnames = ['Date','Name', 'Score']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames,lineterminator='\n')
writer.writeheader()
writer.writerow({'Date':'0117',''Name': 'Mike', 'Score': 90})
writer.writerow({'Date':'0317', 'Name': 'Bob', 'Score': 95})
(rowが増えて、個別にrowやfilednameを記述するのが面倒なら、事前に辞書を作成し、
test_score=[
{'Date':'0117','Name':'Mike', 'Score': 90},
{'Date':'0317','Name':'Bob', 'Score': 95}
]
としておいて、
with open("a.csv",'w') as f:
fieldnames = ['Date', 'Name','Score']
writer=csv.DictWriter(f, fieldnames=fieldnames,lineterminator='\n')
writer.writeheader()
writer.writerows(test_score)
としても良い。
1行の書き込みは、writerow で良いけど、複数まとめてはwriterows になります。
拘ってますね。
# writer.はデータを格納しておく変数名なので、自由につければ良い。
#fieldnames=fieldnames と指定すると、Dictionaryの列の順番が保持される。
(fieldnamesは、自分で定義する変数です。)
#filenamesの定義は、 csv.DictWriter(csv_file, fieldnams=['Date','Name', 'Score'])と
直接DictWriterのオプションとして指定することも可能。
これを実行すると、csvに以下のように書き込まれる。
Output in test.csv file
Date,Name,Score
0117,Mike,90
0317,Bob,95
* 個別にrowやfilednameを記述するのが面倒なら、辞書型データを内包するリストを
定義しておいて、csvに書き込むことも可能。
import csv
test_result=[{'Name': 'Mike', 'Score': 90},
{'Name': 'Bob', 'Score': 95}]
with open('quick.csv', 'w') as csv_file:
fieldnames = ['Name', 'Score']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(test_result)
結果は上に同じ。
================
JSON ファイルについて
================
JSON形式のデータは、以下のようにKeyに対する値としてデータが入っているので、
Data = {
"20200709": [
{
"ticker": "NGHC",
"changes": 13.43,
"price": "33.84",
"changesPercentage": "(+65.80%)",
"companyName": "National General Holdings Corp"
},
{
"ticker": "ARRY",
"changes": 17.69,
"price": "46.57",
"changesPercentage": "(+61.25%)",
"companyName": "Array BioPharma Inc."
},
writer.writerowsに読み込ますデータは、
to_csv = Data[20200709]
なので、値までアクセスしておき、
writer.writerows(to_csv)
で読み込ます。
◆------------------------------------------------------------------------------◆
もし、リストと辞書をつかわないで、以下のようにだらだら書くと、import csv
test_score={'Date':'0117','Name':'Mike','Score':'90','Date':'0317','Name':'Bob', 'Score': 95}
with open("a.csv",'w') as f:
fieldnames = ['Date', 'Name','Score']
writer=csv.DictWriter(f, fieldnames=fieldnamesx,lineterminator='\n')
writer.writeheader()
writer.writerow(test_score)
Output:
Date Name Score
317 Bob 95
と、最後の辞書のセットだけが書き込まれる。上書きされちゃうんですね。
◆------------------------------------------------------------------------------◆
(確認:読み込んでみる)
import csv
with open("a.csv","r") as f:
reader = csv.reader(f) ←この例は辞書型内包のリストなので、csv.reader
new_score=[]
for line in reader:
print(line) # <-- ①
new_score.append(line)
print(new_score) <-- ②
Output①: csv.readerなのに辞書のkeyをちゃんと認識してくれている。
['Date', 'Name', 'Score']
['0117', 'Mike', '90']
['0317', 'Bob', '95']
Output②:
[['Date', 'Name', 'Score'], ['0117', 'Mike', '90'], ['0317', 'Bob', '95']]
いや、リストで囲まれてるからkeyを認識するわけではないみたい。
CSVに、以下の辞書を書き込んで、読み込んでみる。
test_score={'Date':'0117','Name':'Mike','Score':'90'}
with open("a.csv",'r') as f:
reader = csv.reader(f)
new_score=[]
for line in reader:
print(line) #output ①
new_score.append(line)
print(new_score) #output ②
で、以下のようにkeyとvalueを分離してくれる。
但し、リストで返される。
Output ①
['Date', 'Name', 'Score']
['0317', 'Bob', '95']
output ②:
[['Date', 'Name', 'Score'], ['0317', 'Bob', '95']]
csvを読み込んだリストを作るとき、形式が変わってしまっているので注意が必要ですね。
==辞書型で読み込む。
import csv
with open("a.csv",'r') as f:
reader = csv.DictReader(f)
new_score=[]
for line in reader:
print(line)
new_score.append(line)
print(new_score)
Output①:
OrderedDict([('Date', '0317'), ('Name', 'Bob'), ('Score', '95')])
Output②:
[OrderedDict([('Date', '0317'), ('Name', 'Bob'), ('Score', '95')])]
csv.readerで読み込むか、csv.DictReaderで読み込むかは、読み込むデータの形式ではなく
読み込んだデータを、どの値で保持したいかの違いで使い分ける、のか?
-------------------------------------------------------------------------------------------------------
発展(1): test1.csvを読み込み、test2.csvに書き込む。
import csv
with open("test1.csv","r") as csv_file:
csv_reader = csv.DictReader(csv_file)
with open("test2.csv", "w") as new_file:
fieldnames =['column1', 'column2', 'column3']
csv_writer = csv.DictWriter(new_file, fieldnames=fieldnames, delimiter='\t')
csv_writer.writeheader()
for line in csv_reader: <-csv_readerはイテラブル。writerは違う。 あたりまえだけど。
csv_writer.writerow(line)
-------------------------------------------------------------------------------------------------------
3. 辞書に追記
openの第二引数: 'a ' : 追記
'w'を指定すると上書きされるが、'a'を指定して書き込むと追記される。
with open('quick.csv', 'a') as csv_file:
fieldnames = ['area', 'original_area','category','answer']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames,lineterminator='\n')
writer.writeheader()
writer.writerow(questions)
area | original_area | category | answer |
A | B | C | D |
area | original_area | category | answer |
A | B | C | D |
area | original_area | category | answer |
1 | 2 | 3 | 4 |
4. 削除
(1) Key による列(row)の削除
==1番最初のと同じ、こんなcsvが作成されていたとする。
test_score=[
{'Date':'0117','Name':'Mike', 'Score': 90},
{'Date':'0317','Name':'Bob', 'Score': 95}
]
with open("a.csv",'w') as f:
fieldnames = ['Date', 'Name','Score']
writer=csv.DictWriter(f, fieldnames=fieldnames,lineterminator='\n')
writer.writeheader()
writer.writerows(test_score)
import csv
test_score=[
{'Date':'0117','Name':'Mike', 'Score': 90},
{'Date':'0317','Name':'Bob', 'Score': 95}
]
with open("a.csv",'r') as f:
csv_reader = csv.DictReader(f)
modified_t=[]
for line in csv_reader:
del line['Date'] <- Key 全体を削除できる。
modified_t.append(line)
print(modified_t)
Output:
[OrderedDict([('Name', 'Mike'), ('Score', '90')]),
OrderedDict([('Name', 'Bob'), ('Score', '95')])]
(2)行(line)の削除
import csv
with open("a.csv",'r') as f:
reader=csv.reader(f)
new_r=[]
for line in reader:
new_r.append(line)
print(new_r) #output ①
new_r.pop(len(new_r)-1) #List番号は0から始まるので1をマイナスしないと。
print(new_r) ♯Output ②
#output ①
[ ['name', 'rank', 'score', 'record'],
['Justine', '1', '10', "['10', '20', '30']"],
['Puth', '2', '20', "['20', '30', '40']"],
['Shia', '3', '30', "['50', '60', '70']"]]
#output ②
[ ['name', 'rank', 'score', 'record'],
['Justine', '1', '10', "['10', '20', '30']"],
['Puth', '2', '20', "['20', '30', '40']"]]
=======================================
◆ Dictionary型のCSVを読み込む
=======================================
上手く構成できなかったけど、もう、だいぶ書いてしまった。
参考)
- Parsing Names From a CSV to an HTML List
https://www.youtube.com/watch?v=bkpLhQd6YQM&spfreload=5
0 件のコメント:
コメントを投稿