2

こんにちは、2 つのファイルからデータを読み込む関数があります。私が望んでいるのは、外側のループが最初のファイルの読み取りを開始し、最初のファイルの lum が定義された値 (LC) より大きい場合、ループは次の反復にスキップすることです。そうでない場合、コードは内側のループに移動し、hlist を読み取り、idc と id が同じであれば x、y、z リストを作成します。idc と id が同じ値でない場合、内側のループの次の繰り返しにスキップします。テストステートメントを印刷すると、内側のループが繰り返されていないように見え、その理由がわかりません。助けていただければ幸いです

コード

def read_file(F):      #Function that reads data froma file #and extracts specific data columns
    X_pos = []
    Y_pos = []                # Creats Data Lists
    Z_pos = []
    Idh = []
    Id = []
    LC = float(sys.argv[1]) 
    N = 11#912639            # number of lines to be read
    Nl = 11#896030
    fl = open(Fl)            #opens catalog file
    fl.readline()
    nlines_catalog = islice(fl, Nl)
    f = open(F)           #Opens hlist file
    f.readline()          # Strips Header
    nlines_hlist = islice(f, N) #slices file to only read N lines

    for linel in nlines_catalog:
            if linel != '':
              linel = linel.strip()              
              linel = linel.replace('\t', '')
              columnsl = linel.split()
              lum = float(columnsl[1])
              id_catalog = int(columnsl[0])
              if lum >= LC:
                 continue
              print("lum1 =", lum)
              #Id.append(idc)
              print("id_catalog=", id_catalog)
              for line in nlines_hlist:
                 if line != '':
                    line = line.strip()
                    line = line.replace('\t', ' ')
                    columns = line.split()
                    id_hlist = int(columns[1])
                    #Idh.append(id)
                     if id_hlist != id_ccatalog:
                        continue
                    print('idc =', idc, 'id =', id)
                    x = columns[17]           
                    y = columns[18]
                    z = columns[19]
                    X_pos.append(x)
                    Y_pos.append(y)                #appends data in list
                    Z_pos.append(z)

    print(X)
    X = [float(p) for p in X_pos]        
    Y = [float(p) for p in Y_pos]
    Z = [float(p) for p in Z_pos]
    Xa = numpy.array(X, dtype=float)
    Ya = numpy.array(Y, dtype=float)
    Za = numpy.array(Z, dtype=float)


    return(Xa, Ya, Za)

編集

内部ループをリセットして機能するように変更。

 if id_catalog ==  id_halo:
      print('id_catalog =',id_catalog,'id_halo =',id_halo)
      x = columns[17]             # assigns variable to columns
      y = columns[18]
      z = columns[19]
      #vx = columns[]
      #vy = columns[]
      #vz = columns[]
      X_pos.append(x)
      Y_pos.append(y)                #appends data in list
      Z_pos.append(z)
      break

編集 私は、印刷されたステートメントからの元の出力を再現できず、その事実を反映するように編集しました

VirtualBox:~$ python /home/Astrophysics/Count_FixedLoop.py -21.5 125
('lum1 =', -21.78545)
('idc=', 2701276876L)
('idc =', 2701276876L, 'id =', 2701276876L)
('lum1 =', -21.69835)
('idc=', 2699751347L)
('lum1 =', -21.69942)
('idc=', 2699724518L)
('lum1 =', -21.74543)
('idc=', 2699724331L)
('lum1 =', -21.60912)
('idc=', 2699724726L)
('lum1 =', -21.53862)
('idc=', 2699725014L)
('lum1 =', -21.53155)
('idc=', 2701277269L)
['34.57223']

これは私が出力として期待するものです

 ('lum1 =', -21.78545)
 ('idc=', 2701276876L)
 ('idc =', 2701276876L, 'id =', 2701276876L)
 ('lum1 =', -21.69835)
 ('idc=', 2699751347L)
 ('idc =', 2699751347L, 'id =', 2699751347L)
 ('lum1 =', -21.69942)
 ('idc=', 2699724518L)
 ('idc =', 2699724518L, 'id =', 2699724518L)
 ('lum1 =', -21.74543)
 ('idc=', 2699724331L)
 ('idc =', 2699724331L, 'id =', 2699724331L)
 ('lum1 =', -21.60912)
 ('idc=', 2699724726L)
 ('idc =', 2699724726L, 'id =', 2699724726L)
 ('lum1 =', -21.53862)
 ('idc=', 2699725014L)
 ('idc =', 2699725014L, 'id =', 2699725014L)
 ('lum1 =', -21.53155)
 ('idc=', 2701277269L)

編集

idc 番号が column[0] で、lum 値が column[1] である Fl ファイルの数行のサンプル。最初のループで条件を満たす idc 値を太字で示しています。

Format: ID, scatter = 0 0.05 0.1 0.13 0.15 0.16 0.18 0.2 0.25 0.3
**2701276876 -21.78545** -21.73791 -21.68872 -21.11125 -20.88102 -22.04709 -21.41715       -20.56944 -20.36757 -19.69895
**2699751347 -21.69835** -21.67935 -21.92425 -21.03465 -21.56561 -21.42124 -21.72893 -20.78131 -20.76342 -20.34830
**2699724518 -21.69942** -21.58352 -21.71149 -21.16240 -21.18507 -22.00277 -21.81500 -20.36141 -20.78227 -20.65697

編集

最初のファイルと一致する ID と対応する位置を持つ F ファイルのサンプル行

#Scale(0) Id(1) Desc_scale(2) Descid(3) Num_prog(4) Pid(5) Upid(6) Desc_pid(7)   Phantom(8) Mvir(9) Orig_Mvir(10) Rvir(11) Rs(12) Vrms(13) Mmp(14) Last_mm(15) Vmax(16) X(17) Y(18) Z(19) 
 0.9523 **2701276876** 0.9583 2714557311      1       -1       -1       -1  0     3.56533e+13 3.56100e+13 695.459000 80.562000 548.820000  1 0.3603 561.490000 **34.57223 140.20813 130.81985** -110.000 323.430 -123.520 3.56533e+13 3.56533e+13 561.490000 599.410000 7.539e+14 -3.799e+12 -1.992e+14 0.10259
0.9523 **2699751347** 0.9583 2713034575      4       -1       -1       -1  0 3.36604e+13 3.31300e+13 678.981000 111.199000 500.400000  1 0.8083 514.010000 **28.70439 138.70247 138.52176** -215.310 252.520 -120.970 3.36604e+13 3.36604e+13 514.010000 599.250000 5.516e+14 1.044e+14 6.133e+14 0.10973
0.9523 **2699724518** 0.9583 2713007786      1       -1       -1       -1  0 2.98000e+13 2.97500e+13 654.997000 87.324000 457.460000  1 0.4863 514.660000 **8.01627 135.31783 123.13322** -178.990 558.900 1.250 2.98000e+13 2.98000e+13 514.660000 514.660000 8.529e+14 2.711e+14 -3.624e+14 0.15137

私が期待しているのは、両方のファイルの ID が一致すると、2 番目のループが X、Y、および Z 位置リストを追加することです。したがって、この例のリストを印刷すると、

X = [34.57223,28.70439,8.01627]
Y = [140.20813,138.70247,135.31783]
Z = [130.81985,138.52176,123.13322]
4

1 に答える 1

2

listnlinesのように動作することを期待しているようです。ただし、代わりにiteratorであり、上で Ignacio が指摘したように、一度消費されます。つまり、内側のループは、後続の外側のループの実行で最初の行/インデックスに「リセット」されません。

あなたがしていることに次の類似物を考えてください(私は思います)。以下に 2 つのデータ ファイルを示します。

データ1:

file 1: one
file 1: two
file 1: three
file 1: four
file 1: five

データ 2:

file 2: one
file 2: two
file 2: three
file 2: four
file 2: five
file 2: six

これを実行する:

from itertools import islice

f1 = open ("Data1")
f2 = open ("Data2")

iterator1 = islice (f1, 3)
iterator2 = islice (f2, 3)

for line1 in iterator1:
    print line1

    for line2 in iterator2:
       print line2

結果:

file 1: one
file 2: one
file 2: two
file 2: three
file 1: two
file 1: three

一方data2、 の最初の 3 行ごとに、 の内容の 3 行が出力されると誤って予想するかもしれませんdata1

そのため、内側のループの最初の実行で が完全に消費 iterator2されます。id == idc独自のコードでは、内部ループが最初に実行されるときにインターレーターをnlines完全に消費する場合、内部ループの中断はありません。

別の例については、 Python: itertools.islice がループで機能しないも参照してください。

1つの解決策は、ときに内部ループを中断することかもしれませんがid == idc、これは(私が思うに)2番目のファイルのインデックスの順序を想定しています。実際の(非テスト)データのサイズを考えると、メモリを大量に消費するように見えますが、実際には内側のループにリストを使用することを検討できます。パフォーマンスは低下しますが、明らかにその 2 番目のファイルを再読み込みできます。

于 2012-07-24T19:15:25.597 に答える