1

問題:

  1. 入力はタブ区切りファイルです。行は変数で、列はサンプルです。変数は3つの値(00,01,11)をとることができ、管理する必要のある順序(v1-> vN)でリストされます。行と列が多数あるため、入力ファイルをブロック単位で読み取る必要があります。

    入力は次のようになります。

       s1 s2 s3 s4
    v1 00 00 11 01
    v2 00 00 00 00
    v3 01 11 00 00
    v4 00 00 00 00
    (...)
    
  2. 私がやろうとしているのは、入力をいくつかの行の断片に分割することです。断片は、サンプルがそれぞれ一意であるのに十分な大きさです。上記の例では、v1から開始して、最初のブロックはv3で終了する必要があります。これは、その時点でサンプルが一意であるという十分な情報があるためです。次のブロックはv4から始まり、プロセスを繰り返します。最後の行に到達すると、タスクは終了します。ブロックは出力ファイルに印刷されます。


私の試み:

私がやろうとしていたのは、csvモジュールを使用して、すべてのサンプルの単一の変数(00,01,00)の状態をそれぞれ含むリストで構成される配列を生成することです。または、入力をピボットして、各変数のサンプル状態を含むリストを作成します。作業の焦点を列と行のどちらにするか、つまりv1 = ['00'、' 00'、' 11'、'01']またはs1= ['00'、'を使用する方がよいかどうかを尋ねています。 00'、' 01'、' 00'、...]

次のコードは、列の問題を行の問題に変更しようとしたピボット操作を示しています。(不器用なPython構文については申し訳ありませんが、私ができる最善の方法です)

my_infilename='my_file.txt'
csv_infile=csv.reader(open(my_infilename,'r'), delimiter='\t')
out=open('transposed_'+my_infilename, 'w')
csv_infile=zip(*csv_infile)
line_n=0
for line in csv_infile:
line_n+=1
    if line_n==1:    #headers
        continue
    else:
        line=(','.join(line)+'\n')  #just to make it readable to me
        out.write(line)
out.close()

この問題に取り組むための最良の方法は何ですか?ピボットは役に立ちますか?信頼できる組み込み関数はありますか?

4

2 に答える 2

2

すべて同じ長さのリストのリストとしてインポートされたcsvデータを取得すると仮定すると、これはどのように機能しますか...

def get_block(data_rows):
    samples = []

    for cell in data_rows[0]:
        samples.append('')

    # add one row at a time to each sample and see if all are unique
    for row_index, row in enumerate(data_rows):
        for cell_index, cell in enumerate(row):
            samples[cell_index] = '%s%s' % (samples[cell_index], cell)

        are_all_unique = True
        sample_dict = {} # use dictionary keys to find repeats
        for sample in samples:
            if sample_dict.get(sample):
                # already there, so another row needed
                are_all_unique = False
                break
            sample_dict[sample] = True # add the key to the dictionary
        if are_all_unique:
            return True, row_index

    return False, None

def get_all_blocks(all_rows):
    remaining_rows = all_rows[:] # make a copy    
    blocks = []

    while True:
        found_block, block_end_index = get_block(remaining_rows)
        if found_block:
            blocks.append(remaining_rows[:block_end_index+1])
            remaining_rows = remaining_rows[block_end_index+1:]
            if not remaining_rows:
                break
        else:
            blocks.append(remaining_rows[:])
            break

    return blocks


if __name__ == "__main__":
    v1 = ['00', '00', '11', '01']
    v2 = ['00', '00', '00', '00']
    v3 = ['01', '11', '00', '00']
    v4 = ['00', '00', '00', '00']

    all_rows = [v1, v2, v3, v4]

    blocks = get_all_blocks(all_rows)

    for index, block in enumerate(blocks):
        print "This is block %s." % index
        for row in block:
            print row
        print

=================

これはブロック0です。

['00'、' 00'、' 11'、' 01']

['00'、' 00'、' 00'、' 00']

['01'、' 11'、' 00'、' 00']

これはブロック1です。

['00'、' 00'、' 00'、' 00']

于 2012-04-17T17:59:23.517 に答える
0

私はあなたの問題をまったく理解していません(「座標変数」?「一義的にサンプルを決定する」?)が、あなたがcsvモジュールを間違って使用していて、インデントも間違っていることを知っています。

入力ファイルがどのように表示されるかは正確にはわかりませんが、タブ区切りであると仮定すると、次の(テストされていない)スクリプトは、入力ファイルからブロックを取得し、それらを回転させ、出力ファイルに書き換える1つの方法を示しています。

import csv

# this is not strictly necessary, but you can define a custom dialect for input and output

class SampleDialect (csv.Dialect):
    delimiter = "\t"
    quoting = csv.QUOTE_NONE    

sampledialect = SampleDialect()

ifn = 'my_file.txt'
ofn = 'transposed_'+ifn

ifp = open(ifn, 'rb')
ofp = open(ofn, 'wb')

incsv = csv.reader(ifp, dialect=sampledialect)
outcsv = csv.writer(ofp, dialect=sampledialect)


header = None
block = []
for lineno, samples in enumerate(incsv):
    if lineno==0: #header
        header = samples
        continue
    block.append(samples)
    if lineno%3:
        # end of block
        # do something with block
        # then write it out
        outcsv.writerows(block)
        block = []

ifp.close()
ofp.close()
于 2012-04-17T17:21:54.690 に答える