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

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

新規登録して質問してみよう
ただいま回答率
85.47%
Python 3.x

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

Q&A

解決済

2回答

1866閲覧

複数の変数の候補値の中からそれぞれ値を選んで、決まった数だけ組合せを作りたい

MOSMOS2

総合スコア20

Python 3.x

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

1グッド

1クリップ

投稿2018/09/11 19:35

編集2018/09/12 16:40

下記のように、複数の変数に候補の数字があります。

variables = {'variable1': [1, 2, 3, 4, 5],
'variable2': [0, 10, 20, 30],
'variable3': [5, 10, 15, 20]
}

これから各変数から値を1つずつとって、組合せを作りたいと考えています。
例えば、[2, 10, 15]のといった形となります。
これを100通り作るとか数も指定できるようにしたいです。
number_of_samples = 100

ただし、下記の条件で発生させたいと思います。
(1) 重複したものは除く
(2) 例えば、variable2と3の和は35以下にする
(3) 発生したサンプルの和を30~50に設定する

これを表形式(csv)で以下のように出力されていけば嬉しいです。
(順番はランダムでも何でもかまいません)

1, 10, 15
3, 0, 10
2, 20, 5


(とnumber_of_samplesの数だけ発生)

一連の流れについてご教授いただけると幸いです。
よろしくお願いいたします。

tachikoma👍を押しています

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2018/09/11 22:37

どこまでできているのか(どこが自分でできるか)を書きましょう。
R.Shigemori

2018/09/11 23:20

やりたいことはわかりましたが、何が問題なのかが分かりません。何ができていて何ができていないのかを示したほうがいいと思います
tachikoma

2018/09/12 00:01

csvに書き出す順番はランダム?
guest

回答2

0

ベストアンサー

とりあえず、単純に
(1) 各リストからの全ての組み合わせを求める
(2) 上記の組み合わせから条件で絞る
(3) その中からランダムでN個サンプルする
をそのまま組んでみるとよいのではないでしょうか

(1)は iteratools.product()にて実装できます
直積集合を求める
https://docs.python.jp/3/library/itertools.html#itertools.product

Python

1v0 = variables['variable1'] 2v1 = variables['variable2'] 3v2 = variables['variable3'] 4p1 = itertools.product(v0,v1,v2)

(2)は単純にループや内包表記などで実装できます

Python

1p2 = [d for d in p1 if d[1]+d[2]<=35] 2print(p2)

(3)はrandom.sample()で実装できます
リストの中から重複なしのN個の要素を返す
https://docs.python.jp/3/library/random.html#random.sample

Python

1N = 10 2res = random.sample(p2, N) 3print(res) 4

ということで、まとめるとこんな感じ

Python

1from itertools import product 2from random import sample 3 4number_of_samples = 10 5variables = { 6 'variable1': [1, 2, 3, 4, 5], 7 'variable2': [0, 10, 20, 30], 8 'variable3': [5, 10, 15, 20, 100] 9} 10 11v0 = variables['variable1'] 12v1 = variables['variable2'] 13v2 = variables['variable3'] 14res = sample([p for p in product(v0,v1,v2) if p[1]+p[2]<=35], number_of_samples) 15# [(2, 10, 20), (3, 10, 15), (5, 10, 15), (1, 20, 10), (1, 30, 5), (4, 10, 10), (5, 0, 15), (3, 0, 10), (4, 10, 5), (4, 0, 15)]

投稿2018/09/11 23:46

magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MOSMOS2

2018/09/12 19:00

できました!大変勉強になりました。ありがとうございました。
guest

0

variables = {'variable1': [1, 2, 3, 4, 5],

'variable2': [0, 10, 20, 30],
'variable3': [5, 10, 15, 20]
}
これから各変数から値を1つずつとって、組合せを作りたいです。

python

1from itertools import product 2cmb = product( 3 variables["variable1"], 4 variables["variable2"], 5 variables["variable3"]) 6# items = list(cmb)

(1) 重複したものは除く

これはすでに満たされています。

(2) 例えば、variable2と3の和は35以下にする

filterlambdaを使ってみましょうか。

Python

1from itertools import product 2cmb = product( 3 variables["variable1"], 4 variables["variable2"], 5 variables["variable3"]) 6 7maxlimit = 35 8cmbf = filter(lambda x: x[1] + x[2] < maxlimit, cmb) 9# items = list(cmbf)

書き出し部分にはいろいろな方法がありますが、ここではprintでやってみましょうか(オプションの意味は興味があれば調べてみてください)。

number_of_samples = 30 with open("temp.csv", "w") as f: for i, items in enumerate(cmbf): if i == number_of_samples: # 特定回数書き出したら終了する break print(*items, sep=",", end="\n", file=f)

投稿2018/09/11 23:56

編集2018/09/12 00:09
tachikoma

総合スコア3601

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tachikoma

2018/09/12 00:14 編集

イテレータの遅延評価を利用しているので最初はとっつきにくいかもしれませんが、組み合わせの全要素を展開することはしないためメモリ効率はいいはず(予想+期待)。
MOSMOS2

2018/09/12 19:00

ありがとうございます。csvファイルを開いたところ空でした、、がサンプルの抽出まではできました。大変助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問