システム開発<基本編>Pythonでファイルの操作(CSV→JSON)

Python

前回までの2つの記事では、形態素解析器(MeCab)形態素解析器(janome)について

解析処理を深堀りした記事を紹介しました。

2つの記事の中でも、テキストファイルへの書き込みについて少し触れましたが、今回は、

ファイル読み込み書き込みについて、同時に処理を行う記事を紹介します。

 

ファイルの読み込み処理

先ず、ファイル読み込み処理を実装します。

今回は、CSVファイル読み込みたいと思います。

CSVファイルは、現在も多くの現場や企業で、データのやり取り等で利用されている

ファイル形式なので、エンジニアでは無い方でも、御存知の方が多いと思います。

 

読み込み元ファイル

読み込み元となるファイルとして、カンマ区切りCSVファイルを準備します。

今回は、漫画や映画、ドラマで有名な「ちはやふる」「百人一首」のデータを利用します。

ちなみに、「百人一首」の英語表現は、One Hundred Poets, One Poem Each のようです。

CSVファイルの構成は、【 歌番号, 歌(漢字含む), 歌(ひらがな), 歌人 】とします。

ファイル名は、poem_utf-8.csv として、文字コード:UTF-8 で保存します。

1,秋の田の かりほの庵の 苫をあらみ わが衣手は 露にぬれつつ,あきのたの かりほのいほの とまをあらみ わがころもでは つゆにぬれつつ,天智天皇
2,春すぎて 夏来にけらし 白妙の 衣ほすてふ 天の香具山,はるすぎて なつきにけらし しろたへの ころもほすてふ あまのかぐやま,持統天皇
3,あしびきの 山鳥の尾の しだり尾の ながながし夜を ひとりかも寝む,あしびきの やまどりのをの しだりをの ながながしよを ひとりかもねむ,柿本人麻呂
4,田子の浦に うち出でてみれば 白妙の 富士の高嶺に 雪は降りつつ,たごのうらに うちいでてみれば しろたへの ふじのたかねに ゆきはふりつつ,山部赤人
5,奥山に 紅葉踏みわけ 鳴く鹿の 声きく時ぞ 秋は悲しき,おくやまに もみぢふみわけ なくしかの こゑきくときぞ あきはかなしき,猿丸大夫
6,かささぎの 渡せる橋に おく霜の 白きをみれば 夜ぞふけにける,かささぎの わたせるはしに おくしもの しろきをみれば よぞふけにける,中納言家持
7,天の原 ふりさけ見れば 春日なる 三笠の山に 出でし月かも,あまのはら ふりさけみれば かすがなる みかさのやまに いでしつきかも,安倍仲麿
8,わが庵は 都のたつみ しかぞすむ 世をうぢ山と 人はいふなり,わがいほは みやこのたつみ しかぞすむ よをうぢやまと ひとはいふなり,喜撰法師
9,花の色は うつりにけりな いたづらに わが身世にふる ながめせしまに,はなのいろは うつりにけりな いたづらに わがみよにふる ながめせしまに,小野小町
10,これやこの 行くも帰るも 別れては 知るも知らぬも 逢坂の関,これやこの ゆくもかへるも わかれては しるもしらぬも あふさかのせき,蝉丸
11,わたの原 八十島かけて 漕ぎ出でぬと 人には告げよ 海人の釣舟,わたのはら やそしまかけて こぎいでぬと ひとにはつげよ あまのつりぶね,参議篁
12,天つ風 雲の通ひ路 吹き閉ぢよ をとめの姿 しばしとどめむ,あまつかぜ くものかよひぢ ふきとぢよ をとめのすがた しばしとどめむ,僧正遍照
13,筑波嶺の 峰より落つる 男女川 恋ぞつもりて 淵となりぬる,つくばねの みねよりおつる みなのがは こひぞつもりて ふちとなりぬる,陽成院
14,陸奥の しのぶもぢずり 誰ゆゑに 乱れそめにし われならなくに,みちのくの しのぶもぢずり たれゆゑに みだれそめにし われならなくに,河原左大臣
15,君がため 春の野に出でて 若菜つむ わが衣手に 雪は降りつつ,きみがため はるののにいでて わかなつむ わがころもでに ゆきはふりつつ,光孝天皇
16,たち別れ いなばの山の 峰に生ふる まつとし聞かば 今帰り来む,たちわかれ いなばのやまの みねにおふる まつとしきかば いまかへりこむ,中納言行平
17,ちはやぶる 神代も聞かず 竜田川 からくれなゐに 水くくるとは,ちはやぶる かみよもきかず たつたがは からくれなゐに みづくくるとは,在原業平朝臣
18,住の江の 岸による波 よるさへや 夢の通ひ路 人めよくらむ,すみのえの きしによるなみ よるさへや ゆめのかよひぢ ひとめよくらむ,藤原敏行朝臣
19,難波潟 みじかき芦の ふしの間も 逢はでこの世を 過ぐしてよとや,なにはがた みじかきあしの ふしのまも あはでこのよを すぐしてよとや,伊勢
20,わびぬれば 今はた同じ 難波なる みをつくしても 逢はむとぞ思ふ,わびぬれば いまはたおなじ なにはなる みをつくしても あはむとぞおもふ,元良親王
21,今来むと 言ひしばかりに 長月の 有明の月を 待ち出でつるかな,いまこむと いひしばかりに ながつきの ありあけのつきを まちいでつるかな,素性法師
22,吹くからに 秋の草木の しをるれば むべ山風を 嵐といふらむ,ふくからに あきのくさきの しをるれば むべやまかぜを あらしといふらむ,文屋康秀
23,月見れば ちぢにものこそ 悲しけれ わが身一つの 秋にはあらねど,つきみれば ちぢにものこそ かなしけれ わがみひとつの あきにはあらねど,大江千里
24,このたびは ぬさもとりあへず 手向山 紅葉の錦 神のまにまに,このたびは ぬさもとりあへず たむけやま もみぢのにしき かみのまにまに,菅家
25,名にしおはば 逢坂山の さねかづら 人にしられで くるよしもがな,なにしおはば あふさかやまの さねかづら ひとにしられで くるよしもがな,三条右大臣
26,小倉山 峰のもみぢ葉 心あらば 今ひとたびの みゆき待たなむ,をぐらやま みねのもみぢば こころあらば いまひとたびの みゆきまたなむ,貞信公
27,みかの原 わきて流るる 泉川 いつ見きとてか 恋しかるらむ,みかのはら わきてながるる いづみがは いつみきとてか こひしかるらむ,中納言兼輔
28,山里は 冬ぞさびしさ まさりける 人目も草も かれぬと思へば,やまざとは ふゆぞさびしさ まさりける ひとめもくさも かれぬとおもへば,源宗于朝臣
29,心あてに 折らばや折らむ 初霜の 置きまどはせる 白菊の花,こころあてに をらばやをらむ はつしもの おきまどはせる しらぎくのはな,凡河内躬恒
30,有明の つれなく見えし 別れより あかつきばかり 憂きものはなし,ありあけの つれなくみえし わかれより あかつきばかり うきものはなし,壬生忠岑
31,朝ぼらけ 有明の月と 見るまでに 吉野の里に 降れる白雪,あさぼらけ ありあけのつきと みるまでに よしののさとに ふれるしらゆき,坂上是則
32,山川に 風のかけたる しがらみは 流れもあへぬ 紅葉なりけり,やまがはに かぜのかけたる しがらみは ながれもあへぬ もみぢなりけり,春道列樹
33,ひさかたの 光のどけき 春の日に 静心なく 花の散るらむ,ひさかたの ひかりのどけき はるのひに しづごころなく はなのちるらむ,紀友則
34,誰をかも 知る人にせむ 高砂の 松も昔の 友ならなくに,たれをかも しるひとにせむ たかさごの まつもむかしの ともならなくに,藤原興風
35,人はいさ 心も知らず ふるさとは 花ぞ昔の 香ににほひける,ひとはいさ こころもしらず ふるさとは はなぞむかしの かににほひける,紀貫之
36,夏の夜は まだ宵ながら 明けぬるを 雲のいづこに 月宿るらむ,なつのよは まだよひながら あけぬるを くものいづこに つきやどるらむ,清原深養父
37,白露に 風の吹きしく 秋の野は つらぬきとめぬ 玉ぞ散りける,しらつゆに かぜのふきしく あきののは つらぬきとめぬ たまぞちりける,文屋朝康
38,忘らるる 身をば思はず 誓ひてし 人の命の 惜しくもあるかな,わすらるる みをばおもはず ちかひてし ひとのいのちの をしくもあるかな,右近
39,浅茅生の 小野の篠原 しのぶれど あまりてなどか 人の恋しき,あさぢふの をののしのはら しのぶれど あまりてなどか ひとのこひしき,参議等
40,しのぶれど 色に出でにけり わが恋は 物や思ふと 人の問ふまで,しのぶれど いろにいでにけり わがこひは ものやおもふと ひとのとふまで,平兼盛
41,恋すてふ わが名はまだき 立ちにけり 人知れずこそ 思ひそめしか,こひすてふ わがなはまだき たちにけり ひとしれずこそ おもひそめしか,壬生忠見
42,契りきな かたみに袖を しぼりつつ 末の松山 波越さじとは,ちぎりきな かたみにそでを しぼりつつ すゑのまつやま なみこさじとは,清原元輔
43,逢ひ見ての のちの心に くらぶれば 昔は物を 思はざりけり,あひみての のちのこころに くらぶれば むかしはものを おもはざりけり,権中納言敦忠
44,逢ふことの 絶えてしなくは なかなかに 人をも身をも 恨みざらまし,あふことの たえてしなくは なかなかに ひとをもみをも うらみざらまし,中納言朝忠
45,あはれとも いふべき人は 思ほえで 身のいたづらに なりぬべきかな,あはれとも いふべき人は 思ほえで 身のいたづらに なりぬべきかな,謙徳公
46,由良のとを 渡る舟人 かぢを絶え ゆくへも知らぬ 恋の道かな,ゆらのとを わたるふなびと かぢをたえ ゆくへもしらぬ こひのみちかな,曾禰好忠
47,八重葎 しげれる宿の さびしきに 人こそ見えね 秋は来にけり,やへむぐら しげれるやどの さびしきに ひとこそみえね あきはきにけり,恵慶法師
48,風をいたみ 岩うつ波の おのれのみ くだけて物を 思ふころかな,かぜをいたみ いはうつなみの おのれのみ くだけてものを おもふころかな,源重之
49,みかきもり 衛士のたく火の 夜は燃え 昼は消えつつ 物をこそ思へ,みかきもり ゑじのたくひの よるはもえ ひるはきえつつ ものをこそおもへ,大中臣能宣
50,君がため 惜しからざりし 命さへ 長くもがなと 思ひけるかな,きみがため をしからざりし いのちさへ ながくもがなと おもひけるかな,藤原義孝
51,かくとだに えやはいぶきの さしも草 さしも知らじな 燃ゆる思ひを,かくとだに えやはいぶきの さしもぐさ さしもしらじな もゆるおもひを,藤原実方朝臣
52,明けぬれば 暮るるものとは 知りながら なほうらめしき 朝ぼらけかな,あけぬれば くるるものとは しりながら なほうらめしき あさぼらけかな,藤原道信朝臣
53,嘆きつつ ひとり寝る夜の 明くる間は いかに久しき ものとかは知る,なげきつつ ひとりぬるよの あくるまは いかにひさしき ものとかはしる,右大将道綱母
54,忘れじの 行く末までは かたければ 今日を限りの 命ともがな,わすれじの ゆくすゑまでは かたければ けふをかぎりの いのちともがな,儀同三司母
55,滝の音は 絶えて久しく なりぬれど 名こそ流れて なほ聞こえけれ,たきのおとは たえてひさしく なりぬれど なこそながれて なほきこえけれ,大納言公任
56,あらざらむ この世のほかの 思ひ出に 今ひとたびの 逢ふこともがな,あらざらむ このよのほかの おもひでに いまひとたびの あふこともがな,和泉式部
57,めぐりあひて 見しやそれとも わかぬ間に 雲がくれにし 夜半の月かな,めぐりあひて みしやそれとも わかぬまに くもがくれにし よはのつきかな,紫式部
58,有馬山 猪名の笹原 風吹けば いでそよ人を 忘れやはする,ありまやま ゐなのささはら かぜふけば いでそよひとを わすれやはする,大弐三位
59,やすらはで 寝なましものを さ夜更けて かたぶくまでの 月を見しかな,やすらはで ねなましものを さよふけて かたぶくまでの つきをみしかな,赤染衛門
60,大江山 いく野の道の 遠ければ まだふみもみず 天の橋立,おほえやま いくののみちの とほければ まだふみもみず あまのはしだて,小式部内侍
61,いにしへの 奈良の都の 八重桜 けふ九重に にほひぬるかな,いにしへの ならのみやこの やへざくら けふここのへに にほひぬるかな,伊勢大輔
62,夜をこめて 鳥のそらねは はかるとも よに逢坂の 関はゆるさじ,よをこめて とりのそらねは はかるとも よにあふさかの せきはゆるさじ,清少納言
63,今はただ 思ひ絶えなむ とばかりを 人づてならで 言ふよしもがな,いまはただ おもひたえなむ とばかりを ひとづてならで いふよしもがな,左京大夫道雅
64,朝ぼらけ 宇治の川霧 たえだえに あらはれわたる 瀬々の網代木,あさぼらけ うぢのかはぎり たえだえに あらはれわたる せぜのあじろぎ,権中納言定頼
65,恨みわび ほさぬ袖だに あるものを 恋に朽ちなむ 名こそ惜しけれ,うらみわび ほさぬそでだに あるものを こひにくちなむ なこそをしけれ,相模
66,もろともに あはれと思へ 山桜 花よりほかに 知る人もなし,もろともに あはれとおもへ やまざくら はなよりほかに しるひともなし,前大僧正行尊
67,春の夜の 夢ばかりなる 手枕に かひなく立たむ 名こそ惜しけれ,はるのよの ゆめばかりなる たまくらに かひなくたたむ なこそをしけれ,周防内侍
68,心にも あらでうき世に ながらへば 恋しかるべき 夜半の月かな,こころにも あらでうきよに ながらへば こひしかるべき よはのつきかな,三条院
69,嵐吹く み室の山の もみぢ葉は 竜田の川の 錦なりけり,あらしふく みむろのやまの もみぢばは たつたのかはの にしきなりけり,能因法師
70,さびしさに 宿を立ち出でて ながむれば いづこも同じ 秋の夕暮れ,さびしさに やどをたちいでて ながむれば いづこもおなじ あきのゆふぐれ,良暹法師
71,夕されば 門田の稲葉 おとづれて 芦のまろやに 秋風ぞ吹く,ゆふされば かどたのいなば おとづれて あしのまろやに あきかぜぞふく,大納言経信
72,音に聞く 高師の浜の あだ波は かけじや袖の ぬれもこそすれ,おとにきく たかしのはまの あだなみは かけじやそでの ぬれもこそすれ,祐子内親王家紀伊
73,高砂の 尾の上の桜 咲きにけり 外山の霞 立たずもあらなむ,たかさごの をのへのさくら さきにけり とやまのかすみ たたずもあらなむ,権中納言匡房
74,憂かりける 人を初瀬の 山おろしよ はげしかれとは 祈らぬものを,うかりける ひとをはつせの やまおろしよ はげしかれとは いのらぬものを,源俊頼朝臣
75,契りおきし させもが露を 命にて あはれ今年の 秋もいぬめり,ちぎりおきし させもがつゆを いのちにて あはれことしの あきもいぬめり,藤原基俊
76,わたの原 漕ぎ出でて見れば ひさかたの 雲居にまがふ 沖つ白波,わたのはら こぎいでてみれば ひさかたの くもゐにまがふ おきつしらなみ,法性寺入道前関白太政大臣
77,瀬をはやみ 岩にせかるる 滝川の われても末に あはむとぞ思ふ,せをはやみ いはにせかるる たきがはの われてもすゑに あはむとぞおもふ,崇徳院
78,淡路島 かよふ千鳥の 鳴く声に いく夜寝覚めぬ 須磨の関守,あはぢしま かよふちどりの なくこゑに いくよねざめぬ すまのせきもり,源兼昌
79,秋風に たなびく雲の 絶え間より もれ出づる月の 影のさやけさ,あきかぜに たなびくくもの たえまより もれいづるつきの かげのさやけさ,左京大夫顕輔
80,長からむ 心も知らず 黒髪の 乱れて今朝は 物をこそ思へ,ながからむ こころもしらず くろかみの みだれてけさは ものをこそおもへ,待賢門院堀河
81,ほととぎす 鳴きつる方を ながむれば ただ有明の 月ぞ残れる,ほととぎす なきつるかたを ながむれば ただありあけの つきぞのこれる,後徳大寺左大臣
82,思ひわび さても命は あるものを 憂きにたへぬは 涙なりけり,おもひわび さてもいのちは あるものを うきにたへぬは なみだなりけり,道因法師
83,世の中よ 道こそなけれ 思ひ入る 山の奥にも 鹿ぞ鳴くなる,よのなかよ みちこそなけれ おもひいる やまのおくにも しかぞなくなる,皇太后宮大夫俊成
84,長らへば またこのごろや しのばれむ 憂しと見し世ぞ 今は恋しき,ながらへば またこのごろや しのばれむ うしとみしよぞ いまはこひしき,藤原清輔朝臣
85,夜もすがら 物思ふころは 明けやらで 閨のひまさへ つれなかりけり,よもすがら ものおもふころは あけやらで ねやのひまさへ つれなかりけり,俊恵法師
86,嘆けとて 月やは物を 思はする かこち顔なる わが涙かな,なげけとて つきやはものを おもはする かこちがほなる わがなみだかな,西行法師
87,村雨の 露もまだひぬ 真木の葉に 霧立ちのぼる 秋の夕暮れ,むらさめの つゆもまだひぬ まきのはに きりたちのぼる あきのゆふぐれ,寂蓮法師
88,難波江の 芦のかりねの ひとよゆゑ みをつくしてや 恋ひわたるべき,なにはえの あしのかりねの ひとよゆゑ みをつくしてや こひわたるべき,皇嘉門院別当
89,玉の緒よ 絶えなば絶えね ながらへば 忍ぶることの よわりもぞする,たまのをよ たえなばたえね ながらへば しのぶることの よわりもぞする,式子内親王
90,見せばやな 雄島のあまの 袖だにも ぬれにぞぬれし 色はかはらず,みせばやな をじまのあまの そでだにも ぬれにぞぬれし いろはかはらず,殷富門院大輔
91,きりぎりす 鳴くや霜夜の さむしろに 衣かたしき ひとりかも寝む,きりぎりす なくやしもよの さむしろに ころもかたしき ひとりかもねむ,後京極摂政前太政大臣
92,わが袖は 潮干に見えぬ 沖の石の 人こそ知らね かわく間もなし,わがそでは しほひにみえぬ おきのいしの ひとこそしらね かわくまもなし,二条院讃岐
93,世の中は 常にもがもな 渚こぐ あまの小舟の 綱手かなしも,よのなかは つねにもがもな なぎさこぐ あまのをぶねの つなでかなしも,鎌倉右大臣
94,み吉野の 山の秋風 さ夜更けて ふるさと寒く 衣うつなり,みよしのの やまのあきかぜ さよふけて ふるさとさむく ころもうつなり,参議雅経
95,おほけなく うき世の民に おほふかな わが立つ杣に 墨染の袖,おほけなく うきよのたみに おほふかな わがたつそまに すみぞめのそで,前大僧正慈円
96,花さそふ 嵐の庭の 雪ならで ふりゆくものは わが身なりけり,はなさそふ あらしのにはの ゆきならで ふりゆくものは わがみなりけり,入道前太政大臣
97,来ぬ人を まつほの浦の 夕なぎに 焼くや藻塩の 身もこがれつつ,こぬひとを まつほのうらの ゆふなぎに やくやもしほの みもこがれつつ,権中納言定家
98,風そよぐ ならの小川の 夕暮れは みそぎぞ夏の しるしなりける,かぜそよぐ ならのをがはの ゆふぐれは みそぎぞなつの しるしなりける,従二位家隆
99,人も惜し 人も恨めし あぢきなく 世を思ふゆゑに 物思ふ身は,ひともをし ひともうらめし あぢきなく よをおもふゆゑに ものおもふみは,後鳥羽院
100,ももしきや 古き軒端の しのぶにも なほあまりある 昔なりけり,ももしきや ふるきのきばの しのぶにも なほあまりある むかしなりけり,順徳院

参考サイトは、下記になります。

 

CSVファイルの読み込み処理

Pythonファイル読み込みは、基本的に下記のような処理を行います。


import csv

in_file = 'c:/work/python/data/poem_utf-8.csv'

f = open(in_file, mode='r', encoding='utf-8')

rows = csv.reader(f)

for row in rows:

    print(row) 

f.close()

CSVファイルPythonで操作するため、csvモジュールを読み込みます。

open()メソッドで、モード:’r’文字コード:UTF-8 を指定してCSVファイルを開きます。

開いたCSVファイルから、全てのデータを取り出し、変数:rowsの中に保存しています。

for文を使って、変数:rowsに保存されているデータを1行ずつ取り出し、

print関数を使って、コンソール画面に行データを表示させます。

変数:rowsに保存されているデータを全て表示させた後、close()メソッドを使って、

開いたCSVファイルを閉じています。

 

モードの設定は、下記の通りです。
r:読み込み(read)用
w:書き込み(write)用で、ファイルを上書きします
a:書き込み(add)用で、ファイルの最下位から追記します
x:排他的(exclusive)なファイル生成用で、同名のファイルが存在すれば失敗します

with文の使用を推奨

ファイル読み込み書き込みで、with文を利用する事で、ファイルを自動的にクローズします。
明示的close()メソッドを記述する必要がなくなり、ファイルの閉じ忘れ防止に便利です。
また、ファイルが開いている際にエラーが発生しても、適切な例外処理が行われます。
with文を利用して、上記と同じ処理を行うには、以下のように記述します。

import csv

in_file = 'c:/work/python/data/poem_utf-8.csv'

with open(in_file, mode='r', encoding='utf-8') as f:

    rows = csv.reader(f)

    for row in rows:

        print(row) 

‘\ufeff’ (不可視文字):読み込みエラー

CSVファイル読み込み時に、下記のような ‘\ufeff’ (不可視文字)読み込みエラー
発生する事が有ります。
UTF-8には、テキスト始まりをプログラムに伝える為のデータ内のマークがあります。
これは、通称BOM(Byte Order Mark)と呼ばれますが、このBOM
ユニコード表示が、‘\ufeff’ (不可視文字)になります。
具体的には、ユニコード文字U+FEFF がそのマークとして使用されています。
‘\ufeff’ (不可視文字)読み込みエラーが発生した場合は、encoding=’utf-8′
ではなく encoding=’utf-8-sig‘ 読み込むように修正して下さい。
‘utf-8-sig「sig」は、「signature:署名」の略語です。
下記は、ソースの修正例になります。

import csv

in_file = 'c:/work/python/data/poem_utf-8.csv'

with open(in_file, mode='r', encoding='utf-8-sig') as f:

    rows = csv.reader(f)

    for row in rows:

        print(row) 

CSVファイルの読み込み処理の実行例

実際に、ソースを起動してJSONファイルを生成してみましょう。
作成したソース画面の上部のタブメニューより、Run → Run Module を選択して、
ソースを起動します。
実行結果は、下記の通りです。

 

ファイルの書き込み処理

CSVファイル読み込み処理が実装出来ましたので、次は、JSONファイルへの書き込み処理
を実装してみます。

JSONファイルへの書き込み処理:json.dumps()

ファイル書き込み処理は、読み込み処理と同様に、open()メソッドで、

モード:‘w’文字コード:UTF-8 を指定して、write()メソッドを使用して、

JSONファイルへ書き出します。

基本的には、下記のような処理を行います。


import json

out_file = 'c:/work/python/data/poem_utf-8.json'

items = [
    {
        'poem_no': 1,
        'poem_kanji': '秋の田の かりほの庵の 苫をあらみ わが衣手は 露にぬれつつ',
        'poem_kana': 'あきのたの かりほのいほの とまをあらみ わがころもでは つゆにぬれつつ',
        'poem_writer': '天智天皇'
    },
    {
        'poem_no': 17,
        'poem_kanji': 'ちはやぶる 神代も聞かず 竜田川 からくれなゐに 水くくるとは',
        'poem_kana': 'ちはやぶる かみよもきかず たつたがは からくれなゐに みづくくるとは',
        'poem_writer': '在原業平朝臣'
    }
]

json_s = json.dumps(items, indent=4, ensure_ascii=False)

with open(out_file, mode='w', encoding='utf-8') as f:

    f.write(json_s)

print(json_s)

PythonオブジェクトJSON形式の文字列に変換するには、jsonモジュールdumps()
メソッドを利用します。
  • 第一引数:JSONファイルへ出力するJSON形式の内容を指定します。例では、items
  • 第二引数:インデントの深さを指定します。例では、4
  • 第三引数:JSON形式の文字列は、デフォルトではASCII文字列になっている為、日本語がUnicodeエスケープの形式“\uXXXX\uXXXX\uXXXX” で変換されてしまうので、人が読めるように、ensure_ascii=Falseを指定する必要が有ります。
dumps()メソッドは、Pythonオブジェクト(リスト、辞書)を、JSONデータ(文字列
整形する処理ですが、dumps()メソッドだけでは、JSONファイル保存はしませんので、
write()メソッドを使用して、変換したJSONデータJSONファイルとして書き込みます。

 

ensure_ascii=False(非ASCII文字列もエスケープしない)

参考として、ensure_ascii=False 指定しない場合(上段)指定した場合(下段)
実行例になります。

Unicodeエスケープの形式:“\uXXXX\uXXXX\uXXXX” で表示されていると、やはり、

人の目では、どのような文字が記載されているか判断が出来ない状況です。

 

JSONファイルへの書き込み処理:json.dump()

jsonモジュールdump()メソッドを利用した場合は、直接JSONファイル保存が出来ます。
dumps()dump()では、末尾に s の文字が付いているかどうかで、少し混乱しそうですが、
区別をしておきます。
  • json.dumps()Pythonオブジェクト(リスト、辞書)を、JSONデータ(文字列整形
  • json.dump()Pythonオブジェクト(リスト、辞書)を、JSONファイル保存

dump()メソッドは、下記のような処理を行います。


import json
import gc # メモリ処理

out_file = "C:/work/python/data/poem_utf-8_2.json"

try:
    items = [
        {
            'poem_no': 1,
            'poem_kanji': '秋の田の かりほの庵の 苫をあらみ わが衣手は 露にぬれつつ',
            'poem_kana': 'あきのたの かりほのいほの とまをあらみ わがころもでは つゆにぬれつつ',
            'poem_writer': '天智天皇'
        },
        {
            'poem_no': 17,
            'poem_kanji': 'ちはやぶる 神代も聞かず 竜田川 からくれなゐに 水くくるとは',
            'poem_kana': 'ちはやぶる かみよもきかず たつたがは からくれなゐに みづくくるとは',
            'poem_writer': '在原業平朝臣'
        }
    ]
    
    with open(out_file, mode='w', encoding='utf-8') as f:

        json.dump(items, f, indent=4, ensure_ascii=False)

    print(items)

except KeyboardInterrupt:
    gc.collect()

finally:
    gc.collect()

jsonモジュールdump()メソッドを利用した場合の引数は、下記の通りです。

  • 第一引数:JSONファイルへ出力するJSON形式の内容を指定します。例では、items
  • 第二引数:出力ファイルの指定です。例では、f
  • 第三引数:インデントの深さを指定します。例では、4
  • 第四引数:JSON形式の文字列は、デフォルトではASCII文字列になっている為、日本語がUnicodeエスケープの形式“\uXXXX\uXXXX\uXXXX” で変換されてしまうので、人が読めるように、ensure_ascii=Falseを指定する必要が有ります。

 

IDLEコンソールの表示内容やJSONファイルの出力結果は、dumps()メソッドと同じ内容

になります。

 

ファイルの読み込みと書き込みの一括処理

CSVファイル読み込み処理の基本と、JSONファイルへの書き込み処理の基本について、
理解が出来たと思いますので、実際に、「百人一首」の内容が記載されているCSVファイル
読み込み後、JSONファイル書き込みを行う一括処理を実装してみます。

json.dumps()メソッドを利用した一括処理

jsonモジュールdumps()メソッドを利用した、一括処理を紹介します。

import json, csv
import gc # メモリ処理
from datetime import datetime as dt
import time

in_file = "C:/work/python/data/poem_utf-8.csv"
out_file = "C:/work/python/data/poem_kanji_kana_utf-8.json"

items = []

try:
    # 開始時間
    start_time = time.time()

    print("処理開始日時:", dt.now().strftime('%Y/%m/%d %H:%M:%S'))
    print("----------------------------------")
    
    # csvファイル読み込み
    with open(in_file, 'r', encoding='utf-8-sig') as f:
        rows = csv.reader(f)

        for i, row in enumerate(rows):

            # 変数の振り分け
            karuta_no, karuta_kanji, karuta_kana, karuta_writer = row

            items.append({
                'poem_no': int(karuta_no),
                'poem_kanji': karuta_kanji,
                'poem_kana': karuta_kana,
                'poem_writer': karuta_writer,
                'create_datetime': dt.now().strftime('%Y/%m/%d %H:%M:%S'),
                'create_unixtime': time.time() # UNIX時間(エポック秒)
            })             

    # JSONにシリアライズ
    json_s = json.dumps(items, indent=4, ensure_ascii=False)

    print(json_s)
        
    with open(out_file, 'w', encoding='utf-8-sig') as f:
        f.write(json_s)
      
    # 終了時間
    end_time = time.time()

    # 差分
    dif_time = end_time - start_time

    print("----------------------------------")
    print("処理終了日時:", dt.now().strftime('%Y/%m/%d %H:%M:%S'))
    print("----------------------------------")
    print("処理時間:", dif_time , "秒")
    print("----------------------------------")

    print("Poem Read CSV Write JSON Data Succesfully")
    print("----------------------------------")
    print("Total Write Data : %s lines" %(len(items)))
    print("----------------------------------")

except KeyboardInterrupt:
    del items
    
    gc.collect()

finally:
    del items
    
    gc.collect()
処理の説明をしますと、「百人一首」CSVファイルencoding=’utf-8-sig読み込み
【 歌番号, 歌(漢字含む), 歌(ひらがな), 歌人 】の各項目を、下記の変数(値)へ
振り分け処理をしています。
  1. karuta_no歌番号
  2. karuta_kanji歌(漢字)
  3. karuta_kana歌(ひらがな)
  4. karuta_writer歌人
items(dict型)JSONデータを追加する為に、エレメントキー)を指定しています。
  1. poem_nokaruta_no歌番号
  2. poem_kanjikaruta_kanji歌(漢字)
  3. poem_kanakaruta_kana歌(ひらがな)
  4. poem_writerkaruta_writer歌人
  5. create_datetimedt.now().strftime(‘%Y/%m/%d %H:%M:%S’)作成日時
  6. create_unixtimetime.time()UNIX(エポック)時間
作成日時として、datetimeモジュールstrftime()メソッド を利用して、
【現在の日時】→【文字列】フォーマット変換(例:2025/8/27 14:35:39)しています。
strftimeは、「string format time」の略になります。
strftimeフォーマット変換書式コードは、下記を参照して下さい。

 

datetimeモジュールの詳しい使い方に関しては、別の記事で紹介したいと思います。
また、作成日時としてJSONデータには特に必要は無いのですが、システムに携わる際に
関わる可能性が有るので、今回、UNIX(エポック)時間を取り上げました。

 

UNIX時間は、コンピューターシステムにおいて日付と時刻を表現する時間の単位で、1970年1月1日午前0時0分0秒からの経過秒数を指します。
UNIX時間は、32ビットの符号付き整数で表現されていますので、最大値を表現できる範囲が限られています。
・このため、2038年1月19日3時14分7秒(UTC)を超えると、UNIX時間オーバーフローとなり、利用しているプログラムやシステムが誤動作する可能が有ります。
・これが、いわゆる「2038年問題」と呼ばれています。

 

次に、dumps()メソッドで、追加されたitems(dict型)を、JSONデータ(json_s)
変換(シリアライズ:Serialize)しています。
最後に、open()メソッドで、モード:‘w’文字コード:UTF-8 を指定して、
write()メソッドを使用して、JSONファイルへ書き出しています。

 

json.dumps()メソッドを利用した一括処理の実行例

実際に、ソースを起動してJSONファイルを生成してみましょう。
作成したソース画面の上部のタブメニューより、Run → Run Module を選択して、
ソースを起動します。
 
実行結果は、下記の通りです。

最下位まで、スクロールします。

生成したJSONファイルを、開いてみます。

最下位まで、スクロールします。

IDLEJSONファイルも、Unicodeエスケープの形式:“\uXXXX\uXXXX\uXXXX” では
出力されておらず、問題無く、日本語で読める状況です。

 

json.dump()メソッドを利用した一括処理

jsonモジュールdump()メソッドを利用した、一括処理を紹介します。

import json, csv
import gc # メモリ処理
from datetime import datetime as dt
import time

in_file = "C:/work/python/data/poem_utf-8.csv"
out_file = "C:/work/python/data/poem_kanji_kana_utf-8_2.json"

items = []

try:
    # 開始時間
    start_time = time.time()

    print("処理開始日時:", dt.now().strftime('%Y/%m/%d %H:%M:%S'))
    print("----------------------------------")

    # csvファイル読み込み
    with open(in_file, 'r', encoding='utf-8-sig') as f:
        rows = csv.reader(f)

        for i, row in enumerate(rows):

            # 変数の振り分け
            karuta_no, karuta_kanji, karuta_kana, karuta_writer = row

            items.append({
                'poem_no': int(karuta_no),
                'poem_kanji': karuta_kanji,
                'poem_kana': karuta_kana,
                'poem_writer': karuta_writer,
                'create_datetime': dt.now().strftime('%Y/%m/%d %H:%M:%S'),
                'create_unixtime': time.time() # UNIX時間(エポック秒)
            })             

    with open(out_file, 'w', encoding='utf-8-sig') as f:
        json.dump(items, f, indent=4, ensure_ascii=False)

    for item in items;
        print(item)

    # 終了時間
    end_time = time.time()

    # 差分
    dif_time = end_time - start_time

    print("----------------------------------")
    print("処理終了日時:", dt.now().strftime('%Y/%m/%d %H:%M:%S'))
    print("----------------------------------")
    print("処理時間:", dif_time , "秒")
    print("----------------------------------")

    print("Poem Read CSV Write JSON Data Succesfully")
    print("----------------------------------")
    print("Total Write Data : %s lines" %(len(items)))
    print("----------------------------------")

except KeyboardInterrupt:
    del items
    
    gc.collect()

finally:
    del items
    
    gc.collect()

dumps()メソッドと同様に、「百人一首」CSVファイルencoding=’utf-8-sig
読み込み【 歌番号, 歌(漢字含む), 歌(ひらがな), 歌人 】の各項目を、下記の
変数(値)へ振り分け処理をしています。
  1. karuta_no歌番号
  2. karuta_kanji歌(漢字)
  3. karuta_kana歌(ひらがな)
  4. karuta_writer歌人
items(dict型)JSONデータを追加する為に、エレメントキー)を指定しています。
  1. poem_nokaruta_no歌番号
  2. poem_kanjikaruta_kanji歌(漢字)
  3. poem_kanakaruta_kana歌(ひらがな)
  4. poem_writerkaruta_writer歌人
  5. create_datetimedt.now().strftime(‘%Y/%m/%d %H:%M:%S’)作成日時
  6. create_unixtimetime.time()UNIX(エポック)時間
次に、open()メソッドで、モード:‘w’文字コード:UTF-8 を指定して、
dump()メソッドを使用して、追加されたitems(dict型)JSONファイル
書き出しています。

 

json.dump()メソッドを利用した一括処理の実行例

実際に、ソースを起動してJSONファイルを生成してみましょう。
作成したソース画面の上部のタブメニューより、Run → Run Module を選択して、
ソースを起動します。
実行結果は、下記の通りです。
最下位まで、スクロールします。
IDLEコンソールへ出力する際、注意が必要になります。
ソース例では、items の内容をfor文を利用して、print(itemIDLEコンソール
順次出力しています。
もし、for文を利用せず、print(itemsで一括表示の処理を実装してしまいますと、
メモリーリークする恐れが有りますので、ご注意下さい。

    with open(out_file, 'w', encoding='utf-8-sig') as f:
        json.dump(items, f, indent=4, ensure_ascii=False)

    for item in items;
        print(item)
生成したJSONファイルを、開いてみます。
最下位まで、スクロールします。
IDLEJSONファイルも、Unicodeエスケープの形式:“\uXXXX\uXXXX\uXXXX” では
出力されておらず、問題無く、日本語で読める状況です。

 

まとめ

今回は、「百人一首」CSVファイル読み込みJSONファイル書き込む一括処理について、
ソース例と実行結果を紹介して、深堀りして来ました。
最後に、もう一度、今回のポイントを紹介しておきます。
  1. ファイル読み込み書き込みで、with文を利用する事を推奨
  2. ‘\ufeff’ (不可視文字)読み込みエラー時の対処方法は、encoding=’utf-8-sig指定
  3. json.dumps()Pythonオブジェクト(リスト、辞書)を、JSONデータ(文字列変換
  4. json.dump()Pythonオブジェクト(リスト、辞書)を、JSONファイル保存
  5. Unicodeエスケープの形式“\uXXXX\uXXXX\uXXXX” を、人が読めるように対処方法
  6. datetimeモジュールstrftime() を利用して、【現在の日時】→【文字列】変換
  7. UNIX(エポック)時間は、1970年1月1日午前0時0分0秒からの経過秒数で表す

 

次回は、今回作成したJSONファイル読み込みCSVファイル書き込みを一括処理で行う

Pythonでファイルの操作(JSON→CSV)の記事を紹介したいと思います。

また、datetimeモジュールの詳しい使い方に関しては、別の記事で紹介したいと思います。

 

コメント

タイトルとURLをコピーしました