グループ分けされた数字にラベル付けをしたい。
for文を多用した上、if文を用いてスマートじゃないので、
斬新なアイデアが有れば、お教え下さい。
数字は0から11の12個で、
無秩序に下記のように3グループに分かれています。
第1ぐ[4,5,9,10]
[0,2,7]
[1,3,6,8,11]
ラベルは
[1, 2, 1, 2, 0, 0, 2, 1, 2, 0, 0, 2]
と出力されます。
import itertools classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] temp_list = list(itertools.chain.from_iterable(classes)) target = list(range(len(temp_list))) index = list(range(len(temp_list))) for i, id_class in enumerate(classes): for k in range(len(id_class)): for j in range(len(index)): if index[j]==id_class[k]: target[j] = i print(target)
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答8件
0
ベストアンサー
python
1import numpy as np 2 3classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 4 5arr = np.concatenate(classes) 6lengths = list(map(len, classes)) 7w = np.repeat(np.arange(len(lengths)), lengths) 8 9np.bincount(arr, w) 10# array([1., 2., 1., 2., 0., 0., 2., 1., 2., 0., 0., 2.])
投稿2020/12/08 04:16
総合スコア1399
0
3つ目のforループは不要ではないでしょうか。
python
1classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 2 3target = [-1] * 12 4# target = [-1] * (max(itertools.chain.from_iterable(classes)) + 1) 5 6for i, id_class in enumerate(classes): 7 for j in id_class: 8 target[j] = i
また、numpyを使っていいなら、forループはひとつで書けます。
python
1import numpy as np 2 3classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 4 5target_arr = np.empty(12, dtype=int) 6for i, id_class in enumerate(classes): 7 target_arr[id_class] = i 8target = target_arr.tolist()
投稿2020/12/07 23:15
編集2020/12/08 00:32総合スコア4794
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
val -> label の dict をつくり、range(12) に対して、この dict を map するという方針で書いてみました。
python3
1classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 2 3labels = [[idx] * len(classes[idx]) for idx in range(len(classes))] 4val_label_hash = dict(zip(sum(classes, []), sum(labels, []))) 5print(list(map(lambda x: val_label_hash[x], range(len(val_label_hash))))) 6 7print() 8print("classes=", classes) 9print(" labels=", labels) 10print("val_label_hash=", val_label_hash)
参考情報
- Pythonでflatten(多次元リストを一次元に平坦化)
投稿2020/12/07 21:38
総合スコア22324
0
あまり使われない collections.ChainMap
を使ってみました。
python
1from collections import ChainMap 2 3classes = [[4,5,9,10], [0,2,7], [1,3,6,8,11]] 4c = ChainMap(*map(lambda x: dict.fromkeys(x[1], x[0]), enumerate(classes))) 5ans = list(map(lambda i: c[i], range(12))) 6print(ans)
再帰を使った別案です。
python
1def solve(n, row=0): 2 return row if n in classes[row] else solve(n, row+1) 3 4classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 5ans = list(map(solve, range(12))) 6print(ans) 7
投稿2020/12/07 14:02
編集2020/12/08 03:36退会済みユーザー
総合スコア0
0
for を使わなければいいんですよね。
Python
1import itertools 2 3classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 4 5target = list(itertools.chain.from_iterable(classes)) 6def g(i, a): 7 if a: 8 target[a[0]] = i 9 g(i, a[1:]) 10def f(i, a): 11 if a: 12 g(i, a[0]) 13 f(i+1, a[1:]) 14f(0, classes) 15 16print(target)
追記
import itertools なしで、全部自前でやるとすれば、
Python
1classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 2 3def h(a, i): 4 return len(a[0]) + h(a[1:], i+1) if a else 0 5target = [0] * h(classes, 0) 6def g(a, i): 7 if a: target[a[0]] = i; g(a[1:], i) 8def f(a, i): 9 if a: g(a[0], i); f(a[1:], i+1) 10f(classes, 0) 11 12print(target)
追記2
a[1:] で新しいリストを作るのは無駄なので、
Python
1classes = [[4, 5, 9, 10], [0, 2, 7], [1, 3, 6, 8, 11]] 2 3def h(i): 4 return len(classes[i-1]) + h(i-1) if i > 0 else 0 5target = [0] * h(len(classes)) 6def g(a, j, i): 7 if j > 0: target[a[j-1]] = i; g(a, j-1, i) 8def f(i): 9 if i > 0: i -= 1; g(classes[i], len(classes[i]), i); f(i) 10f(len(classes)) 11 12print(target)
投稿2020/12/08 01:50
編集2020/12/08 04:54総合スコア8224
0
Python
1classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 2 3print([z[1] for z in sorted(sum([[(x,y) for x in w] for w, y in zip(classes,range(len(classes)))],[]))])
と、書いてみた物の、for
が3回出てきます。
投稿2020/12/07 13:28
総合スコア85886
0
やってみました。
python
1def check(n, classes): 2 for idx, lst in enumerate(classes): 3 if n in lst: 4 return idx 5 6classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 7target = list(range(11)) 8 9[check(i, classes) for i in target]
もうちょっと、よくできるかなぁ。
投稿2020/12/07 13:11
総合スコア13758
0
中間リストを作ると楽だと思います。
このコードが簡潔だと感じるかどうかは慣れ次第ですが。
Python
1import operator as op 2 3classes = [[4,5,9,10],[0,2,7],[1,3,6,8,11]] 4 5it = [ 6 (clazz, e) 7 for clazz, es in enumerate(classes) 8 for e in es 9] 10print(f'{it=}') 11 12dst = [ 13 e for e, _ in sorted(it, key=op.itemgetter(1)) 14] 15print(f'{dst=}')
実行結果 Wandbox
it=[(0, 4), (0, 5), (0, 9), (0, 10), (1, 0), (1, 2), (1, 7), (2, 1), (2, 3), (2, 6), (2, 8), (2, 11)] dst=[1, 2, 1, 2, 0, 0, 2, 1, 2, 0, 0, 2]
投稿2020/12/07 12:53
編集2020/12/07 12:56総合スコア35668
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/10 05:02