0

リストから特定の数の行を削除するロジックを記述し、削除する行をできるだけ均等に選択したいと考えています。これは、リストから 25% または 50% を削除したい場合に簡単です。単に 4 行目または 2 行ごとに削除するロジックを記述します。ただし、きれいに分割されていない数値を削除し、できるだけ均等に配置できるようにするロジックを作成するにはどうすればよいでしょうか?

たとえば、1000 のリストから、たとえば 40% をできるだけ均等に削除するために、どの行を削除するかを決定するにはどうすればよいでしょうか? 場合によっては 3 行ごと (33%)、場合によっては 2 行ごと (50%) を削除する必要があることはわかっていますが、どの行を削除するかを決定するルーチンを考え出していません。リスト。

4

1 に答える 1

0

基本的な考え方は、レコードを削除する前に、最初にいくつのレコードを通過する必要があるかを計算することです。これは浮動小数点数でなければなりません。例えば:

percentage = 37.0
lineCount = 912.0
deleteEveryN = 100.0 / percentage    # ~2.702 lines

次に、関連するすべての行を削除して、行を数えるだけです。浮動小数点を使用すると、すべてのN行のみを削除する状況を回避できます。値によってはN-1またはになる場合があります。N+1

countToNextDeletion = deleteEveryN / 2
foreach line:
    countToNextDeletion = countToNextDeletion - 1.0
    if countToNextDeletion <= 0.0:
        delete line
        countToNextDeletion = countToNextDeletion + deleteEveryN

countToNextDeletion行数を半分に初期化する理由は、両端のバランスを可能な限り整えるためです (削除を中間点で対称にします)。これは、私が線画アルゴリズムで学んだトリックです (Bresenham から、記憶から)。そうしないと、削除ポイントに到達せずに最終グループで 97% しか取得できないため、期待どおりに削除できない可能性があります。

このアルゴリズムの動作は、次の Python プログラムで確認できます。

percentage = 37
lineCount = 97
deleteEveryN = 100.0 / percentage
print "Delete every %f" % deleteEveryN

delCount = 0
countToNextDeletion = deleteEveryN / 2
for n in range (lineCount):
    countToNextDeletion = countToNextDeletion - 1.0
    if countToNextDeletion <= 0.0:
        print "Deleting %d" % n
        delCount = delCount + 1
        countToNextDeletion = countToNextDeletion + deleteEveryN

print "Deleted %d/%d (%f%%)" % (delCount, lineCount, delCount*100.0/lineCount)

この出力は次のとおりです (垂直方向のスペースを節約するために出力をわずかに変更します)。

pax> python testprog.py
Delete every 2.702703
Deleting 1
Deleting 4
Deleting 6
Deleting 9
Deleting 12
Deleting 14
Deleting 17
Deleting 20
Deleting 22
Deleting 25, 28, 31, 33, 36, 39, 41, 44, 47, 49, 52, 55, 58
Deleting 60, 63, 66, 68, 71, 74, 77, 79, 82, 85, 87, 90, 93
Deleting 95
Deleted 36/97 (37.113402%)

しきい値に応じて、2 行ごとに削除されることもあれば、3 行ごとに削除されることもあります (everyN値が であるため、2 よりも 3 の方が多い2.7ish)。

最後の行は、これが特定のデータに最適であることも示しています。

linesDeleted/lineCount  percentage  deltaPercentage (from 37)
======================  ==========  =========================
                 35/97  36.0824742      0.9175258
                 36/97  37.1134021      0.1134021 <== closest
                 37/97  38.1443299      1.1443299

最初の数回の反復でどのように機能するかを示すために、最初はまたはcountToNextDeletionに設定されています。最初の行では、 getに追加しますが、それはしきい値を超えていません。2.7027027 / 21.3513514012.3513514

2 行目で、get に追加して1しきい値を超えているので、行を削除してしきい値を引いて get にします。13.35135140.6486487

次に、しきい値を超えるまでさらに3 行かかり3.6486487、その時点で行を削除し4てしきい値を引いて を取得します0.945946

そこからあと22.945946行で に到達し、しきい値を超えるので、削除6してしきい値を引いて を取得します0.2432433

したがって、基本的には、リストを通過している場所を非常に詳細 (浮動小数点) で覚えていますが、整数の境界でのみ削除しています。

于 2013-02-27T05:17:46.000 に答える