Serviceを読んで理解し、同意したものとみなします。スタック・オーバーフローはプログラマーとプログラミングに熱心な人のためのQ&Aサイトです。2,958件31python3.x系です。以下のようなテキストファイル(original.txt)があります。data4_3これを以下の3つのテキストファイルに分割したいのです。data4_3・1列目のデータをキーワードにしてファイルを分割したい。・1列目のデータ(=分割された後にできるファイル数)はこの例だと3つだが、何個であっても対応できるようにしたいそこで、以下の部分までコードを考えました。query_keyとここまで書いて、ファイルハンドルを動的に(=キーワードの種類数に合わせて自動的に)生成する方法を思いつかず、行き詰まりました。ファイルハンドルが動的に複数生成できれば、複数のファイルを開いて書き込むことができます。perlだと「ファイルハンドルとして未定義のスカラ変数が与えられたとき、ファイルハンドルを自動的に生成し変数に設定する」ということで、これを用いて動的に生成できるようです。pythonはどうも違うらしいのです。そこで、ここから先どうしたらよいかお知恵を拝借したいのです。以上の方法だと、仮にファイルハンドルを動的に生成できたとしても、ファイルをいくつも同時に開きっぱなしにすることになる・・・かな。すると、original.txtが大きい場合、メモリに負担になりそうな気がします。この点もあわせてお知恵をお借りできればと思います。15:40行毎に追記モードopen(filename,"a")で開いてすぐ閉じるとか。17:51さすがに効率が悪そうでやめました。data.tsv(出力ファイルをtruncateしていませんけれども)。票1ジェネレータを使ってみました(エラーチェックはしていません)。files.values()]以上の方法だと、仮にファイルハンドルを動的に生成できたとしても、ファイルをいくつも同時に開きっぱなしにすることになる・・・かな。すると、original.txtが大きい場合、メモリに負担になりそうな気がします。さんの言われる「開いて閉じて」を繰り返すのも一手ですが、一行毎では少し効率がよろしくないと思いますので、一定量をバッファリングして定期的にファイルへ出力するなどすると良いかもしれません。17:49(↑途中で書き込んでしまいました。17:50及びませんでした。ありがとうございました。|1設問者のコメントを見る限りバッファリングやストリーミング処理は必要ないと思うので、オンメモリでの回答を示します。modeで開きread_csvのchunksizeという引数を設定すれば同じような考え方で処理できます。pandasとnumpyを使用します。pd要件を満たすような巨大なダミーデータ(1.2GB)を作成しテストしてみます、メモリが足りない場合は、N_sampleを小さくしてください。#ダミーデータファイル作成tsvの読み込みには注意が必要なので2つ例示しますpandasではデータ型(dtype)という概念があり、例えば数値として解釈できる文字列が入力されると自動的にfloat64とかにキャストされます。数値であっても文字列として処理したい場合は下のほうの記述のほうが安全です。メモリ消費量については僕の環境では上の記述は0.6GB程度、下の記述では4.8GB程度メモリを消費しています。最後に目的の処理を記述します、リスト内包表記を使えば一行で書けますが割愛します。df[df[0]==idx].to_csv(str(idx)+".csv",sep="\t",index=None,header=None)df[0]はキーワードを表している列。df[0].unique()はユニークなキーワードのリストです、この例ではdummy_idxsと同じです。indexingと呼ばれているもので、例えばdf[df[0]=='aaa']とするとキーワードが'aaa'となっている行だけを抽出できます。それを'aaa.csv'と名付け、tsv形式で保存しています。1.2GBのファイルでも2分程度で処理できます、1MBなら一瞬でしょう。他にもキーワードと行番号でソートしてからファイル処理をする方法なども考えられますが割愛します。使って実装してみました。original.txtがキーでソートされていると理想的です。|0このトピックを立ち上げたものです。回答いただいた皆さんありがとうございました。自己レスになりますが、ちょっと考えたことがありますので、以下書きます。今日になって「もとのoriginal.txtで、1列目のキーワードがきちんとソートさえされていれば、動的にファイルハンドルを生成する必要なない」ということに気づきました。なんと私は愚かなのでしょうか。そこで、「予めソートされたoriginal.txtを使う」という前提なら、以下のようにできることに気づきました。"w")#1回目用にダミーの書き込みファイルを開けておく。この行はなくてもプログラムは走るが、下部の「前キーワードのファイルハンドルの解放」のときに、if文の1回目だけは解放すべきファイルハンドルがないので、ちょっと気持ち悪い。fh_output.close()os.remove("dummy_file.txt")他の方が提案された方法よりもかなり不格好で長いですが、初学者の私には一番理解し易い、逐次的な方法になりました。これを書いていて感じたことがあります。pythonのファイルハンドルのスコープはどうなっているのだろう?ということです。globalのように思えるのですが、はっきりと記載したサイトなどがなく、ちょっと引っかかっています。inputfile.txt";という未定義の変数を用いたopenの方法だとlocalにすることもできるようです。pythonだとこの方法はエラーになるのかな、たぶん・・・。strictの条件で)。pythonだとこの方法でlocalになる...のかな?この他、余談ですが、perlだとprintでのファイル書き込みは、デフォルトでブロックバッファリング(一定のデータ量までバッファにデータを蓄積して、超えたら書き出し)のようです。pythonでは違うようで、ファイルクローズ時に一気に書き出しのようですね。ここでの皆さんの解答をみて初めて知りました。ありがとうございます。perlはopenしたファイルをcloseし忘れても、スクリプト終了時に勝手にcloseされるのですが、pythonはopenしっぱなしになるようで、上記スクリプトで最後の「fh_output.close()」をつけ忘れていたら、div.003.txtには何も書かれていませんでした。|回答スタック・オーバーフローに参加してくれて、ありがとうございます!質問の回答を共有してください。回答を説明し、自分の検討結果も共有してください。意見を述べること(意見を述べるなら、参照リソース、自分の経験で意見をサポートしてください)さらにサポートが必要な場合このヘルプを参考してください。“回答を投稿”をクリックすることで利用規約、プライバシーポリシー、及びクッキーポリシーに同意したものとみなされます。タグが付いた他の質問を参照するか、自分で質問をする。質問のフィードこのRSSフィードを購読するには、このURLをコピーしてRSSリーダーに貼り付けてください。