質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

4回答

4332閲覧

Pythonによるデータ加工での大容量csvの扱い

tom_drums

総合スコア8

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/05/14 01:31

Pythonにてメモリに乗り切らない大容量csv(数百GB)の加工の仕方についてアドバイスをください。

処理としては単純で、各レコードを一意に特定するようなIDを新たなカラムに格納していくだけなのですが、加工対象のcsvが大容量でメモリに乗らないため、どのように処理するか悩んでおります。

加工のイメージは以下の通りです。

name, amount, date
tanaka, 1000, 20180101
satou, 1200, 20180101
suzuki, 899, 20180102

といったcsvに対して

tranID, name, amount, date
0001, tanaka, 1000, 20180101
0002, satou, 1200, 20180101
0003, suzuki, 899, 20180102

といった形式で、一意となるIDをふるイメージです。

メモリにのる量であれば、panadsを使ってdataframeでtranIDを必要レコード数分作成し、結合すればよいかと思ったのですが、
今回ファイルサイズが大きいため、1行ずつの処理などが必要と思っておりますが、
いまいちいい書き方が思いつかず、アドバイスをいただけますと幸いです。

使用している環境はPython3系になります。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kunihiro_Narita

2018/05/14 05:43

単純にIDをふるだけなら「1行分を文字列として読む、文字列の先頭にIDを付与する、文字列を1行書く」だけで、わざわざ聞くような話でもないですよね。本当に聞きたいことはBigDataを扱うプログラムの書き方ではないですか?
tom_drums

2018/05/17 05:49

仰る通りで、大目的としてはpythonでbig dataを扱う場合の処理方法を知る必要があるのが背景です。ただ、当方初学者のため、「「1行分を文字列として読む、文字列の先頭にIDを付与する、文字列を1行書く」という処理を巨大なファイルに対して実施する際の書き方に自信がなく、このような質問をさせていただきました。
guest

回答4

0

python上で何らかの発展を考えているなら完全に趣旨違いとなりますが、こういう大きなファイルに対して「一行読んで処理してそのまま読み捨てる」処理だけを試みるなら、awkやperlを使ったほうが遥かにシンプルですね。

sh

1awk 'NR==1{printf("tranID,")} NR>1{printf("%04d,",NR-1)} {print}' input.csv

投稿2018/05/14 05:03

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tom_drums

2018/05/17 05:46

ありがとうございます。 たしかにawkやperlだと簡単そうですね。 今回は、諸事情ありpythonで処理が必要だったため、他の方をベストアンサーにさせていただきました。
guest

0

ベストアンサー

これでCSVを1行ずつコピーしていくコードになるので、これを発展させれば目的の処理は達成できると思います。

python

1from csv import reader, writer 2 3with open("input.csv", encoding="utf-8-sig") as fin: 4 with open("output.csv", "w", encoding="utf-8-sig", newline='') as fout: 5 wt = writer(fout) 6 for row in reader(fin): 7 wt.writerow(row)

投稿2018/05/14 01:55

YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tom_drums

2018/05/17 05:47

ありがとうございます。 いただいたコードをもとに発展させてやりたい処理が実現できました。
guest

0

一度に扱えないサイズのBigDataを処理するための汎用的な話をしますね。

BigDataを扱うには、元となるデータを一度に処理可能な量(数十MB程度)に分割して処理を行うバッチ処理か、最小単位のデータ(1行)毎に処理を行うストリーム処理の何れかになります。

ビッグデータを処理するための環境として知られているApatch Hadoopは前者を、RDBに対するSQL文の処理などは後者の方法を使っています。

今回のように一行ずつのデータに対して処理を行う場合には、バッチ処理でもストリーム処理でも良いのですが、複数の行にまたがった計算処理を行う場合にはバッチ処理でないと難しくなります。例えば時系列にそった移動平均を計算しようとするなら、元となるデータを時系列順に並び替えなくてはなりません。ですが並び替える処理は多くのメモリを使用するため、データ量が多いと一度にはできません。こういう部分はストリーム処理では実現できず、バッチ処理になります。

またビッグデータの処理では、どのような中間データを出力するかが肝になります。移動平均を算出する場合には「順不同の元データ→各月毎のデータに分割→各月毎のデータを並び替え→月毎のデータを結合→移動平均算出」のように、何段階かのバッチ処理に分ける必要があるでしょう。この時に汎用性を考えた中間データを作成しておかないと、異なる集計を行う場合に最初からやり直すために、多くの時間がかかる事になります。

投稿2018/05/18 14:30

Kunihiro_Narita

総合スコア472

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

いまいちいい書き方が思いつかず、アドバイスをいただけますと幸いです。

とりあえず一行ずつだとI/Oがしんどいので、100行とか1000行ずつ読んだら多少マシになったりしないかなぁ、と思いました。

投稿2018/05/14 04:55

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tom_drums

2018/05/17 05:47

確かに一つのやり方としては、なるべく分割して処理する、がセオリーなのかな、と思いました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問