1

物事のリスト、それらの頻度(頻度でソート)、およびアイテムの総数があるとしましょう(ここではわかりやすくするために辞書を使用していますが、実際には頻度プロパティを持つオブジェクトです)。

items = {"bananas":12, "oranges":12, "apples":11, "pears":2}

max_results今、私は私の37( )アイテムから10アイテム()を選びたいと思いますtotal_frequencyが、それらの頻度に比例します(たとえば、任意のアイテムの最大で3つ- max_proportion)。この例では、バナナ、オレンジ、リンゴがそれぞれ3つ、梨が1つになります。

def get_relative_quantities(total_frequency, items, max_results, max_proportion):
    results = {}
    num_added = 0
    for freq, the_group in it.groupby(items, lambda x: x.frequency):
        if num_added == max_results:
            break

        the_group_list = list(the_group)
        group_size = len(the_group_list)
        shuffle(the_group_list)

        for item in the_group_list:
            if num_added == max_results:
                break

            rel_freq = min(math.ceil((freq/total_frequency)*max_results), max_proportion)
            results[item] = rel_freq
            num_added += rel_freq

    return results

私が心配していることの1つは、このアプローチでは、アイテムが1つしかない場合、十分な結果が得られないことです。私はちょうど3を取得します(max_proportion10のうちf 3を想定)。どうすればその問題に取り組むことができますか?

4

3 に答える 3

0

それは、どの戦略があなたのニーズにより適しているかによります。max_resultsあなたがで10あり、あなたmax_proportionがであるとしましょう2。何を返すべきですか?最初の反復は2それぞれを取得します。

  • 結果を破棄してすべてをやり直すと、に増加max_proportion3、梨の数はに減少します1(つまり、結果はあなたの例のようになります)。
  • 結果を保持し、とを使用して新しい反復を行うmax_results = 2max_proportion = 1、バナナとオレンジが1つずつ増えます。
    • そして、max_proportionに保たれている場合2、2つのバナナまたは2つのオレンジを取得する可能性があり、他のいずれも取得しない可能性があります。

希望する出力が何であれ、私の提案は同じです。十分な結果があるかどうかを確認し、必要に応じて、get_relative_quantities減らすmax_results(残りの要素を取得する)か増やすmax_proportion(最初の結果を破棄して各アイテムをどんどん受け入れる)のいずれかでもう一度呼び出します。 )。これを必要な回数だけ実行して、目的の数に到達するか、可能性を使い果たします。(これは反復深化の背後にある同じ原理です)

于 2012-12-27T04:48:33.040 に答える
0

まず、要素の数が比例する項目のリストを作成します。

items = {"bananas":12, "oranges":12, "apples":11, "pears":2}

choices = []
[choices.extend([k] * v) for k, v in items.items()]

次に、それぞれの最小数 (可能な各アイテムの 1 つ) で最終結果を設定します。

selected = list(items.keys())

最後に、選択する残りの項目について、比例的に複製された項目のリストからランダムに 1 つ選択します。

import random as rnd
[selected.append(rnd.choice(choices)) for i in xrange(10 - len(items))]

これらすべてのスニペットを組み合わせたもの:

import random as rnd

items = {"bananas":12, "oranges":12, "apples":11, "pears":2}

choices = []
[choices.extend([k] * v) for k, v in items.items()]

selected = list(items.keys())
[selected.append(rnd.choice(choices)) for i in xrange(10 - len(items))]

そして実行からの出力:

>>> pp.pprint(selected)
['pears',
 'bananas',
 'oranges',
 'apples',
 'bananas',
 'bananas',
 'oranges',
 'apples',
 'apples',
 'apples']
于 2012-12-27T05:45:21.843 に答える