1

私はPythonに少し精通しています。非常に具体的な方法で読み取る必要がある情報を含むファイルがあります。以下は例です...

1
6
0.714285714286
0    0    1.00000000000
0    1    0.61356352337
...
-1  -1    0.00000000000
0    0    5.13787636499
0    1    0.97147643932
...
-1  -1    0.00000000000
0    0    5.13787636499
0    1    0.97147643932
...
-1  -1    0.00000000000
0 0 0 0   5.13787636499
0 0 0 1   0.97147643932
....

したがって、すべてのファイルはこの構造 (タブ区切り) になります。

  • 1 行目と 2 行目、3 行目を変数として読み込む必要があります。
  • 次に、 で区切られた 4 つのコード ブロックがあります-1 -1 0.0000000000。コードの各ブロックの長さは「n」行です。最初の 2 つの数値は、行の 3 番目の数値が配列に挿入される位置/場所を表します。一意の位置のみがリストされます (したがって、位置 0 1 は 1 0 と同じですが、その情報は表示されません)。
  • 注: コードの 4 番目のブロックには、4 つのインデックス番号があります。

必要なもの

  • 最初の 3 行は一意の変数として読み込まれます
  • データの各ブロックは、数値の最初の 2 (または 4) 列を配列インデックスとして使用し、3 番目の列を配列に挿入される値として使用して、配列に読み込まれます。
  • 一意の配列要素のみが表示されます。ミラーリングされた位置にも適切な値を入力する必要があります (0 1値は にも表示されるはずです1 0)。
  • 最後のブロックは、4 次元配列に挿入する必要があります。
4

3 に答える 3

3

コードを書き直しました。今、それはほとんどあなたが必要とするものです。微調整が必​​要なだけです。

私は古い答えを残すことにしました-おそらくそれも役立つでしょう。新しい機能は十分に豊富であり、理解が明確でない場合があるためです。

def the_function(filename):
    """
    returns tuple of list of independent values and list of sparsed arrays as dicts
    e.g. ( [1,2,0.5], [{(0.0):1,(0,1):2},...] )
    on fail prints the reason and returns None:
    e.g. 'failed on text.txt: invalid literal for int() with base 10: '0.0', line: 5'
    """

    # open file and read content
    try:
        with open(filename, "r") as f:
            data_txt = [line.split() for line in f]
    # no such file
    except IOError, e:
        print 'fail on open ' + str(e)

    # try to get the first 3 variables
    try:
        vars =[int(data_txt[0][0]), int(data_txt[1][0]), float(data_txt[2][0])]
    except ValueError,e:
        print 'failed on '+filename+': '+str(e)+', somewhere on lines 1-3'
        return

    # now get arrays
    arrays =[dict()]
    for lineidx, item in enumerate(data_txt[3:]):
        try:
            # for 2d array data
            if len(item) == 3:
                i, j = map(int, item[:2])
                val = float(item[-1])
                # check for 'block separator'
                if (i,j,val) == (-1,-1,0.0):
                    # make new array
                    arrays.append(dict())
                else:
                    # update last, existing
                    arrays[-1][(i,j)] = val
            # almost the same for 4d array data
            if len(item) == 5:
                i, j, k, m = map(int, item[:4])
                val = float(item[-1])
                arrays[-1][(i,j,k,m)] = val
        # if value is unparsable like '0.00' for int or 'text'
        except ValueError,e:
            print 'failed on '+filename+': '+str(e)+', line: '+str(lineidx+3)
            return
    return vars, arrays
于 2012-04-20T15:38:44.610 に答える
2

私はあなたが何を求めたのか理解しています..

# read data from file into list
parsed=[]
with open(filename, "r") as f:
    for line in f:
        # # you can exclude separator here with such code (uncomment) (1)
        # # be careful one zero more, one zero less and it wouldn work
        # if line == '-1  -1    0.00000000000':
        #     continue
        parsed.append(line.split())

# a simpler version
with open(filename, "r") as f:
    # # you can exclude separator here with such code (uncomment, replace) (2)
    # parsed = [line.split() for line in f if line != '-1  -1    0.00000000000']
    parsed = [line.split() for line in f]

# at this point 'parsed' is a list of lists of strings.
# [['1'],['6'],['0.714285714286'],['0', '0', '1.00000000000'],['0', '1', '0.61356352337'] .. ]

# ALT 1 -------------------------------
# we do know the len of each data block 

# get the first 3 lines:
head = parsed[:3]

# get the body:
body = parsed[3:-2]

# get the last 2 lines:
tail = parsed[-2:]

# now you can do anything you want with your data
# but remember to convert str to int or float

# first3 as unique:
unique0 = int(head[0][0])
unique1 = int(head[1][0])
unique2 = float(head[2][0])

# cast body:
# check each item of body has 3 inner items
is_correct = all(map(lambda item: len(item)==3, body))
# parse str and cast
if is_correct:
    for i, j, v in body:
        # # you can exclude separator here (uncomment) (3)
        # # * 1. is the same as float(1)
        # if (i,j,v) == (0,0,1.):
        #     # here we skip iteration for line w/ '-1  -1    0.0...'
        #     # but you can place another code that will be executed 
        #     # at the point where block-termination lines appear
        #     continue 

        some_body_cast_function(int(i), int(j), float(v))
else:
    raise Exception('incorrect body')


# cast tail
# check each item of body has 5 inner items
is_correct = all(map(lambda item: len(item)==5, tail))
# parse str and cast
if is_correct:
    for i, j, k, m, v in body: # 'l' is bad index, because similar to 1.
        some_tail_cast_function(int(i), int(j), int(k), int(m), float(v))
else:
    raise Exception('incorrect tail')

# ALT 2 -----------------------------------
# we do NOT know the len of each data block 

# maybe we have some array?
array = dict() # your array may be other type

v1,v2,v2 = parsed[:3]
unique0 = int(v1[0])
unique1 = int(v2[0])
unique2 = float(v3[0])

for item in parsed[3:]:
    if len(item) == 3:
        i,j,v = item
        i = int(i)
        j = int(j)
        v = float(v)

        # # yo can exclude separator here (uncomment) (4)
        # # * 1. is the same as float(1)
        # # logic is the same as in 3rd variant
        # if (i,j,v) == (0,0,1.):
        #     continue

        # do your stuff
        # for example,
        array[(i,j)]=v
        array[(j,i)]=v

    elif len(item) ==5:
        i, j, k, m, v = item
        i = int(i)
        j = int(j)
        k = int(k)
        m = int(m)
        v = float(v)

        # do your stuff

    else:
        raise Exception('unsupported') # or, maybe just 'pass'
于 2012-04-16T18:25:13.677 に答える
1

ファイルから繰り返し行を読み取るには、次のようなものを使用できます。

with open(filename, "r") as f:
  var1 = int(f.next())
  var2 = int(f.next())
  var3 = float(f.next())
  for line in f:
    do some stuff particular to the line we are on...

ループの外側にいくつかのデータ構造を作成し、それらを上記のループに入れます。文字列を要素に分割するには、次を使用できます。

>>> "spam   ham".split()
['spam', 'ham']

numpyまた、配列データ構造のライブラリと、可能であれば分析用のライブラリも見てみたいと思いますSciPy

于 2012-04-16T13:12:52.563 に答える