2

私は Python の初心者で、文字列を含む 2 つのリストの一致に問題がありました。

正規表現を使用して txt メタファイルから Landsat 画像のバンド名を抽出し、次のようなリストを作成しました。

bant = ['LT5YYYYYYYYYYYYYXXX02_B1.TIF', 'LT5YYYYYYYYYYYYYXXX02_B2.TIF','LT5YYYYYYYYYYYYYXXX02_B3.TIF', 'LT5YYYYYYYYYYYYYXXX02_B4.TIF', 'LT5YYYYYYYYYYYYYXXX02_B5.TIF', 'LT5YYYYYYYYYYYYYXXX02_B6.TIF', 'LT5YYYYYYYYYYYYYXXX02_B7.TIF']

「YYYYYYYYYYYYYY」はシーンごとに変わるバンド固有の名前です。そして、各文字列を変数に割り当ててから、新しいリストに割り当てました。

        bant1 = bant[0]
        bant2 = bant[1]
               .
               .
        bant7 = bant[6]
        bant = [bant1,bant2,bant3,bant4,bant5,bant6,bant7]

また、Python os モジュールを使用して、このような txt Metafile と同じディレクトリにある GeoTIFF ファイルの名前を抽出しました。

import os
import re
def mtl():
file=[]
path = os.getcwd()
for filelist in os.listdir(path):
    if filelist.endswith(".TIF"):
        file.append(filelist)

出力付き:

file = ['LT5YYYYYYYYYYYYYXXX02_B1.TIF', 'LT5YYYYYYYYYYYYYXXX02_B2.TIF']

私が立ち往生した問題は、これら2つのリスト、「バント」と「ファイル」をどのように比較できるかということです。リストで見つかったバンドが bant1、bant2 であることを出力します。ファイルリスト内の文字列の数は変更可能です (一部のファイルはユーザーによって削除され、ファイルリストに含まれていない可能性があります)。

私の英語でごめんなさい。助けてくれてありがとう

4

2 に答える 2

5

セット交差点をお探しですか?

In [16]: bant = ['LT5YYYYYYYYYYYYYXXX02_B1.TIF', 'LT5YYYYYYYYYYYYYXXX02_B2.TIF','LT5YYYYYYYYYYYYYXXX02_B3.TIF', 'LT5YYYYYYYYYYYYYXXX02_B4.TIF', 'LT5YYYYYYYYYYYYYXXX02_B5.TIF', 'LT5YYYYYYYYYYYYYXXX02_B6.TIF', 'LT5YYYYYYYYYYYYYXXX02_B7.TIF']

In [17]: file = ['LT5YYYYYYYYYYYYYXXX02_B1.TIF', 'LT5YYYYYYYYYYYYYXXX02_B2.TIF']

In [18]: set(bant).intersection(file)
Out[18]: set(['LT5YYYYYYYYYYYYYXXX02_B1.TIF', 'LT5YYYYYYYYYYYYYXXX02_B2.TIF'])

sets は順序付けされていないため、 によって返される結果はまたはset(bant).intersection(file)によって指定された順序に対応しない場合があることに注意してください。たとえば、の順序を維持する必要がある場合は、次を使用できますbantfilebant

fileset = set(file)
[b for b in bant if b in fileset]

また、定義方法は次のfileように簡略化できます。

import glob
files = glob.glob('*.TIF')

印刷可能です

見つかった (または一致した) バンドは、bant = [bant1,bant2,bant3,bant4,bant5,bant6,bant7] リストを使用して、bant1, bant2" です。

bantでもその前に、bant1、などのアイテムに名前を付けないように説得してもbant2よろしいですか?

アイテムの数は実行時まで不明だとおっしゃっていbantますが、各アイテムに独自の変数名を付けるにはどうすればよいですか? それは可能ですが、必須ではありません。bant[0]代わりにbant1、 、 などの代わりにPython インデックスを使用してください。これを行うことで、番号付きの変数名で各項目を指定しようとする場合よりもはるかに簡単にをプログラムできます。bant[1]bant2bantbant

于 2013-01-04T19:39:56.517 に答える
2

ちなみに、変数に名前を付けないでください。これはfile(Python 2.x の) 組み込み型の名前であるため、使用すると混乱を招きます。また、ファイル名のリストを持っていて、それfilefilenames.

これを行う単純な方法は、ネストされたforループを使用することです。

print('The bands found (or matches) are', end=' ')
for band in bant:
    for filename in filenames:
        if band == filename:
            print(band + ',', end=' ')
            break
print()

ただし、in演​​算子を使用してこれをより簡単にすることができます。

print('The bands found (or matches) are', end=' ')
for band in bant:
    if band in filenames:
        print(band + ',', end=' ')
print()

3.x ではなく Python 2.x を使用している場合は、これを少し変更する必要があります。

print 'The bands found (or matches) are',
for band in bant:
    if band in filenames:
        print band + ',',
print

一致した各バンドの値の代わりにインデックスを出力する場合は、次enumerateのように、インデックスとバンドを同時に反復処理するために を使用できます。

print('The bands found (or matches) are', end=' ')
for i, band in enumerate(bant):
    if band in filenames:
        print('bant{},'.format(i), end=' ')
print()

,とにかく、これは最後に余分なものを残すことに気付くかもしれません. これを修正するには、まだバンドを印刷しているかどうかを追跡し,、最初のバンドを除く各バンドの前に を印刷する必要があります。それはすぐに醜くなります。

これを解決するには、通常、一致のコレクションを作成し、 を使用してそれらを結合しますjoin。このような:

matches = []
for i, band in enumerate(bant):
    if band in filenames:
        matches.append('bant{}'.format(i))
print('The bands found (or matches) are', ', '.join(matches))

ずっときれい。しかし、リスト内包表記を使用すると、これをさらに簡単にすることができます。

matches = ['bant{}'.format(i) for i, band in enumerate(bant) if band in filenames] 
print('The bands found (or matches) are', ', '.join(matches))

append理解と同等のリストを読むと、リストを明示的に作成して何度も呼び出す必要なく、それらが同じことをどのように行っているかを確認できるはずです。

さて、考えてみると、リスト全体をfilenames1 回ずつ線形検索していることに気付くかもしれませんband。たとえば、バンドが 8 つ、ファイル名が 6 つしかない場合は、最悪の場合 48 回の比較になるため、それほど問題にはなりませんが、それぞれが 1000 回ある場合はどうなるでしょうか。1000000 回の比較にはさらに時間がかかります。

filenames変換すると、N 回の比較ではなくset、それぞれが 1 回の比較しか行わないため、それぞれが 1000 回ある場合は、1000000 回ではなく 1000 回の比較しか実行できません。したがって、次のようになります。band in filenames

filenameset = set(filename)
matches = ['bant{}.format(i) for i, band in enumerate(bant) if band in filenameset]
print('The bands found (or matches) are', ', '.join(matches))

改善できる点は他にもありますが、これが機能する理由を理解していれば完了です。

于 2013-01-04T19:52:41.590 に答える