5

私の主な目標は、フロートの巨大な行列から中央値(列ごと)を計算することです。例:

a = numpy.array(([1,1,3,2,7],[4,5,8,2,3],[1,6,9,3,2]))

numpy.median(a, axis=0)

Out[38]: array([ 1.,  5.,  8.,  2.,  3.])

マトリックスが大きすぎてPythonメモリに収まらない(約5テラバイト)ので、csvファイルに保存します。したがって、各列を調べて中央値を計算したいと思います。

ファイル全体を読み取らずに列イテレータを取得する方法はありますか?

行列の中央値を計算することに関する他のアイデアも良いでしょう。ありがとうございました!

4

4 に答える 4

3

各列をメモリに収めることができる場合(できることを暗示しているようです)、これは機能するはずです:

import itertools
import csv

def columns(file_name):
   with open(file_name) as file:
       data = csv.reader(file)
       columns = len(next(data))
   for column in range(columns):
       with open(file_name) as file:
           data = csv.reader(file)
           yield [row[column] for row in data]

これは、列の数を調べてから、ファイルをループして、各行から現在の列の項目を取得することで機能します。これは、最大で、列のサイズにメモリの行のサイズを加えたサイズを一度に使用していることを意味します。とてもシンプルなジェネレーターです。ループするときに反復子を使い果たすため、ファイルを再度開き続ける必要があることに注意してください。

于 2012-09-22T22:16:52.420 に答える
1

csvファイルで要求していることを直接行う方法はおそらくありません(私があなたを誤解していない限り)。問題は、ファイルが固定幅の行を持つように特別に設計されていない限り、ファイルに「列」があるという意味のある意味がないことです。CSVファイルは通常そのように設計されていません。ディスク上では、それらは巨大な文字列にすぎません。

>>> import csv
>>> with open('foo.csv', 'wb') as f:
...     writer = csv.writer(f)
...     for i in range(0, 100, 10):
...         writer.writerow(range(i, i + 10))
... 
>>> with open('foo.csv', 'r') as f:
...     f.read()
... 
'0,1,2,3,4,5,6,7,8,9\r\n10,11,12,13,14,15,16,17,18,19\r\n20..(output truncated)..

ご覧のとおり、列フィールドは予想どおりに整列していません。2番目の列はインデックス2から始まりますが、次の行では、列の幅が1つ増えて、配置がずれます。入力長が変化すると、これはさらに悪化します。結果として、csvリーダーはファイル全体を読み取る必要があり、使用しないデータは破棄されます。(それを気にしないのであれば、それが答えです。ファイル全体を1行ずつ読み、使用しないデータを破棄します。)

スペースを無駄にすることを気にせず、データが固定幅より長くならないことがわかっている場合は、固定幅フィールドを使用してファイルを作成し、オフセットを使用してファイルを検索できます。しかし、それを実行したら、実際のデータベースの使用を開始することもできます。PyTablesは、numpy配列を格納するための多くの人のお気に入りの選択肢のようです。

于 2012-09-22T22:34:28.123 に答える
1

これを行うには、各列に 1 つずつ、N 個の空のファイルを初期化します。次に、行列を 1 行ずつ読み取り、各列のエントリを正しいファイルに送信します。マトリックス全体を処理したら、戻って各ファイルの中央値を順番に計算します。

これは基本的にファイルシステムを使用して行列の転置を行います。転置したら、各行の中央値を計算するのは簡単です。

于 2012-09-22T22:05:02.223 に答える
0

バケットソートを使用すると、すべての列をメモリに読み込まずに、ディスク上の各列を並べ替えることができます。次に、中央の値を選択するだけです。

awkまたは、UNIXとコマンドを使用してsort、中央値を選択する前に列を分割して並べ替えることができます。

于 2012-09-22T22:18:54.477 に答える