0

私のデータファイルは次のようになります。

3.6-band 
6238
Over
0.5678
Over
0.6874
Over
0.7680
Over
0.7834

私がやりたいことは、最小の float とそのすぐ上にある単語を選び出し、それら 2 つの値を出力することです。何をしているかが自分もわからない。私はもう試した

df=open('filepath')
  for line in df:
    df1=line.split()
    df2=min(df1)

これは、少なくとも最小のフロートを分離しようとする私の試みです。問題は、最後の値を与えているだけです。これは、繰り返しを最初からやり直すことを知らないpythonの問題だと思いますが、繰り返します...私が何をしているのかわかりません。試してみdf2=min(df1.seek(0))ましたが成功しませんでした。エラーが表示されましたno attribute seek。それが私がこれまでに試したことです。最小のフロートの前に来る行を印刷する方法はまだわかりません。提案/ヘルプ/アドバイスをいただければ幸いです、ありがとう。

補足として、このデータ ファイルは、同様の特徴を持つより大きなデータ ファイルの例ですが、「Over」という単語は「Under」の場合もある可能性があるため、同様に印刷する必要があります。

4

5 に答える 5

2

リスト、[word,num]ペアのリストにアイテムを保存minしてから、そのリストのリストに適用します。keyのパラメータを使用minして、アイテムの比較に使用するアイテムを指定します。:

with open('abc') as f:
    lis = [[line.strip(),next(f).strip()] for line in f]
    minn = min(lis, key = lambda x: float(x[1]))
    print "\n".join(minn)
...     
Over
0.5678

ここでlisは次のようになります。

[['3.6-band', '6238'], ['Over', '0.5678'], ['Over', '0.6874'], ['Over', '0.7680'], ['Over', '0.7834']]
于 2013-07-07T21:50:13.250 に答える
2

grouper レシピを使用してizip(*[iterator]*2)、行を 2 つのグループにクラスター化できます。次に、行dfの最小ペアを見つけるには、minとそのkeyパラメーターを使用して、比較に使用するプロキシを指定します。この場合、行のペアごと(p, l)に、2 番目の行の float をfloat(l)プロキシとして使用します。

import itertools as IT
with open('filepath') as df:
    previous, minline = min(IT.izip(*[df]*2), 
                            key=lambda (p, l): float(l))
    minline = float(minline)
    print(previous)
    print(minline)

版画

Over

0.5678

ハタのレシピの説明:

ハタのレシピを理解するには、まずdfリストの場合に何が起こるかを見てください。

In [1]: df = [1, 2]

In [2]: [df]*2
Out[2]: [[1, 2], [1, 2]]

Python では、リストに正の整数を掛けると、リスト内の項目の (浅い) コピーがn取得されます。nしたがって、内部[df]*2の 2 つのコピーを持つリストを作成します。df

今考えますzip(*[df]*2)

*inにはzip(*...)特別な意味があります。*に渡される into 引数に続くリストをアンパックするように Python に指示しzipます。したがって、zip(*[df]*2)は とまったく同じですzip(df, df):

In [3]: zip(df, df)
Out[3]: [(1, 1), (2, 2)]

In [4]: zip(*[df]*2)
Out[4]: [(1, 1), (2, 2)]

引数のアンパッキングのより完全な説明は、SaltyCrane here によって提供されます

行っていることzipに注意してください。 zip(*[df]*2)両方のコピーの最初の要素 (この場合は両方とも 1) を剥がし、タプル (1,1) を形成します。次に、両方のコピーの 2 番目の要素 (両方とも 2) を剥がし、タプル (2,2) を形成します。これらのタプルを内部に含むリストを返します。

dfがイテレータの場合に何が起こるかを考えてみましょう。イテレータはリストに似ていますが、イテレータは 1 回のパスのみに適しています。アイテムはイテレータから引き出されるため、イテレータを巻き戻すことはできません。

たとえば、ファイル ハンドルは反復子です。行を含むファイルがあるとします

1
2
3
4

In [8]: f = open('data')

f次のように呼び出すことで、イテレータから項目を取り出すことができますnext(f)

In [9]: next(f)
Out[9]: '1\n'

In [10]: next(f)
Out[10]: '2\n'

In [11]: next(f)
Out[11]: '3\n'

In [12]: next(f)
Out[12]: '4\n'

を呼び出すたびにnext(f)、ファイル ハンドルから次の行を取得しますf。もう一度呼び出すとnext(f)、反復子が空であることを示す StopIteration 例外が発生します。

次に、グルーパー レシピが でどのように動作するかを見てみましょうf

In [14]: f = open('data')  # Notice we have to open the file again, since the old iterator is empty

In [15]: [f]*2
Out[15]: 
[<open file 'data', mode 'r' at 0xa028f98>,
 <open file 'data', mode 'r' at 0xa028f98>]

[f]*2は、同じ iterator の2 つの同一のコピーを含むリストを返しますf

In [16]: zip(*[f]*2)
Out[16]: [('1\n', '2\n'), ('3\n', '4\n')]

zip(*[f]*2)最初のイテレータ から最初のアイテムをf剥がし、次に 2 番目のイテレータ から最初のアイテムを剥がしますfしかし、イテレータはf両方とも同じです! また、反復子は 1 回のパスに適しているため (元に戻ることはできません)、アイテムを剥がすたびに異なるアイテムが得られます。アイテムを剥がすために毎回zip呼び出しています。next(f)したがって、最初のタプルは ('1\n', '2\n'). 同様にzip、最初の iterator から次のアイテムを剥がしf、2 番目の iterator から次のアイテムを剥がしてf、タプルを形成し('3\n', '4\n')ます。したがって、 をzip(*[f]*2)返します [('1\n', '2\n'), ('3\n', '4\n')]

ハタのレシピはこれで全部です。上記では、Python がタプルのリストではなく反復子を返すように、IT.izip代わりに使用することを選択しました。zipファイルに多くの行が含まれている場合、これにより多くのメモリが節約されます。との違いについてはzipこちらでIT.izip詳しく説明しています。

于 2013-07-07T21:51:19.650 に答える
1

使用できません:

min(number)

次のもののみを使用できます。

min(num1, num2)

ファイルが次のようになっている場合:

6238
0.5678
0.6874
0.7680
0.7834

次のコードを使用できます。

Num1 = float(file.readline())

for line in file:
    Num2 = float(line)
    Num1 = min(Num1, Num2)

sがある場合は、"Over"2 行おきにスキップできます。

于 2013-07-07T21:50:27.797 に答える
0

上記の興味深い解決策がいくつかあります。私はこの簡単な解決策を選びます。1 つ問題が残っています。それは、整数もこのように取られる可能性があるということです。これに対する解決策はありますか?

    df=open('myfile.txt')
    lines=df.readlines()
    minval = 1e99
    for n,line in enumerate(lines):
        try: 
            val=float(line)  # NB! like this, also integers will be taken. 
            if val < minval:  
                minval = val
                i_min  = n  
        except:
            pass
    word = lines[i_min-1]
于 2013-07-07T22:30:43.807 に答える
0

おそらく File.readlines() を使用してファイルのすべての行を読み取るか、すでに持っているようなループを使用してから、各行について数値を読み取り (数値の場合)、「これまでで最高」と比較する必要があります。価値。

split() は本当に必要ないようです。あなたがする必要があるのは、各行が数字で始まるかどうかを確認することです。その場合、float(line) で数値を取得できます。空白が問題を引き起こしている場合は、 float(line.strip()) かもしれません。行が数字で始まらない場合は、一時変数に保持します。次の行がこれまでの最良の値よりも低い数値を提供していることが判明した場合は、その一時的な値を一時的な出力用の変数にコピーできます。

于 2013-07-07T21:59:12.737 に答える