質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • Python

    7531questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    5934questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

リスト内からランダムに要素を選択する際に確率を重み付けしたいです

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 244

yuum

score 11

リスト内からランダムに要素を選択する際に確率を重み付けしたいです。この際に重複しないようにするrandom.sample()を用いたいです。
ランダムシャッフルする際にある一定の要素は比較的最初に並ぶようにし、他のある要素は比較的後ろに並ぶようにしたいです。

例:57,58,59,60を前に持っていきたいとき
70,101,103を後ろに持っていきたいとき
list = [16,29,35,55,57,58,59,60,61,62,63,64,69,70,72,101,103]
→list = [72,59,58,57,60,29,35,16,55,63,62,64,69,70,103,101,72]

import random
list = [16,29,35,55,57,58,59,60,61,62,63,64,69,70,72,101,103]#listの要素に重み付けをしたい

n = int(input())

for _ in range(n):
    random.shuffle(list)
    print(list)

    zf = id_worker[:2]

    st = id_worker[2:4]    

    del list[:4]
    print(list)        
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • yuum

    2018/05/28 18:34

    ではなくこちらが指定した要素です

    キャンセル

  • mather

    2018/05/28 18:37

    「前に持っていきたい要素」が「後ろに持っていきたい要素」より必ず前にある状態を作りたいということですか?質問の意図が読みにくいです。

    キャンセル

  • Lhankor_Mhy

    2018/05/28 19:15

    その重みはどのように表現されていますか? 関数化されているのでしょうか?

    キャンセル

回答 3

+1

おそらくこれだろうと思う答えは実装してみたのですが、質問者自身が他の質問でも全く同じコードを提示していたことからも解く努力をしていないと感じたので、ヒントだけお伝えします。

  • 前に持っていきたいリスト、後ろに持っていきたいリスト、どちらにも含まれないリストを作る
  • どのリストをから要素を選択するか、ランダムに決める。このときに重み付けをする。
  • 選んだリストから、ランダムに要素を取り出す。取り出した要素はリストから削除する。
  • 取り出した要素を結果のリストの後ろに追加する。
  • 結果のリストの長さが元のリストの長さになる、または、全部のリストが空になるまで繰り返す。

こういうことでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

次のようなアルゴリズムを考えてみました。

1.まず条件に応じて数字(リストの要素)に値を割り振る

  • 比較的前に置きたい要素
    平均-u標準偏差sの正規分布から取った値を振る
  • 比較的後ろに置きたい要素
    平均u標準偏差sの正規分布から取った値を振る
  • どちらでもない要素
    平均0標準偏差sの正規分布から取った値を振る

2. その値に基いて昇順ソートする
3. 元の値を取り出す

それなりに期待通り動きますし、平均と標準偏差を変えることでどの程度前後に偏るかを調整できます。

import random

def f(x, a={57,58,59,60}, b={70,101,103}, u=1, s=1):
    if x in a:
        return random.gauss(-u, s)
    elif x in b:
        return random.gauss(u, s)
    else:
        return random.gauss(0, s)

lst = [16,29,35,55,57,58,59,60,61,62,63,64,69,70,72,101,103]
result = [x[1] for x in sorted([(f(x), x) for x in lst], key=lambda x:x[0])]
print(result)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

最初に並ぶもの同士および後ろに並ぶもの同士は、一様分布と仮定すると以下のようなコードになると思います。

lists= [1,2,3,4,5,6]  # 選択されるリスト
weight1 = np.array([10,10,10,5,5,5])   # 選択の重み付け(前半部)
weight1 = weight1 / np.sum(weight1)    # 全体で1.0となるように換算
res1 = np.random.choice(lists,size=3,replace=False,p=weight1) # 前半分の3つを選択

weight2 = np.array([5,5,5,10,10,10])   # 後半部の重み付け
weight2 = weight2 / np.sum(weight2)
res2 = np.random.choice(lists,size=4,replace=False,p=weight2)

なお、この方法だと、res1とres2は独立なので重なることが起きます。したがって、上記を実施したのちに重なりのチェックを行い、重なる場合は所定のルールで再選択をコードにする必要があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    ある範囲の整数の和を求めるプログラム

    1から10までの整数の和を求める簡単なプログラムを作っています。 たとえばこれをC言語で実装する場合はfor文を使うのが一般的かと思います。 しかしPythonのfor文はC言語

  • 解決済

    遺伝的アルゴリズムによる特徴選択について

    pythonによる遺伝的アルゴリズムの実装 遺伝的アルゴリズムを使った特徴選択をpythonで実装しようとしているのですが、わからないことがあります。 例えば以下のようなnumoy

  • 解決済

    python3 リストの一括削除等

    前提・実現したいこと pythonでリストの勉強をしております。 多数の数値を格納しているリストを、例えば100以下の数値は一括して削除、もしくは他の数値や文字列に一括して変更する

  • 解決済

    Python 内包表記

    jupyter notebookでとある数列を求めるプログラムを作りました。 for文の中にあるfor文(for j in range(compare.size + 1)...)を

  • 解決済

    Python 3.x 辞書のキー値によって変換する場合の高速化

    Pythonにて、辞書(dict({key,value})を使って、list型の全要素をValue値に変換する際の、 高速化が可能かどうかをご教授いただきたいです。 dict1

  • 解決済

    Pythonのrandomについて

    Pythonのrandomについての質問です。 ディクショナリーの中にある全てのキーをランダムで被り無く、出したいのですがどうすればよいでしょう。 全てのキーは dic

  • 解決済

    二つの配列で重複した内容を取り出したい

     前提・実現したいこと a = [1,3,6,14,30,53,103,106] b = [2,3,7,30,32,64,103,111,200,204] という2つの配列a・b

  • 解決済

    リスト内要素をまとめて削除したい

    リスト内要素を一度消したのちに再度別要素をまとめて消そうとfor文を回したのですがTry-exceptの部分が考慮されずに結果が出てしまいます。 したいこと ①シャッフルされたli

同じタグがついた質問を見る

  • Python

    7531questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    5934questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。