🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
YOLO

YOLOとは、画像検出および認識用ニューラルネットワークです。CベースのDarknetというフレームワークを用いて、画像や動画からオブジェクトを検出。リアルタイムでそれが何になるのかを認識し、分類することができます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

解決済

1回答

1274閲覧

ndarrayの重複要素に対応する他ndarrayの要素をコントロール(削除)したい

P5_USER

総合スコア73

YOLO

YOLOとは、画像検出および認識用ニューラルネットワークです。CベースのDarknetというフレームワークを用いて、画像や動画からオブジェクトを検出。リアルタイムでそれが何になるのかを認識し、分類することができます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

0グッド

0クリップ

投稿2019/12/24 03:57

いつもお世話になっています。

前提・実現したいこと

機械学習の推論過程にて、
同一タグ名の複数検出・描画を1つに絞り込みたいと考えています。

その為、yolo.py内にある
out_classes
out_scores
out_boxes
を使って解決しようとしています。

具体的には
0. out_classes内の重複する要素を検出
0. 重複要素に対応するout_scoresから(重複種類ごとに)最大値を検出
0. out_classesにて重複要素かつout_scoresにて最大値以外を消去してリサイズ
で達成可能かと思っています。

今、2と3で行き詰っています。
どのような関数を使えば解決できますか。

元のデータが

out_classes = np.array([0, 0, 3, 3, 5]) out_scores = np.array([0.99801666, 0.7711145, 0.9962558, 0.96635705, 0.80220133]) out_boxes = np.array( [[ 8.540416, 61.232857, 76.36931, 123.20946 ], [ 10.599434, 67.45303, 75.46433, 115.5706 ], [101.44424, 137.79492, 165.17267, 201.09848 ], [ 90.32121, 60.167862, 160.19128, 126.34792 ], [ 92.46553, 210.28862, 167.8457, 296.00696 ]])

の形になっているので、

out_classes = np.array([0, 3, 5]) out_scores = np.array([0.99801666, 0.9962558, 0.80220133]) out_boxes = np.array( [[ 8.540416, 61.232857, 76.36931, 123.20946 ], [101.44424, 137.79492, 165.17267, 201.09848 ], [ 92.46553, 210.28862, 167.8457, 296.00696 ]])

の様にさせたいです。

該当のソースコード

python

1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4import numpy as np 5 6out_classes = np.array([0, 0, 3, 3, 5]) 7out_scores = np.array([0.99801666, 0.7711145, 0.9962558, 0.96635705, 0.80220133]) 8out_boxes = np.array( 9 [[ 8.540416, 61.232857, 76.36931, 123.20946 ], 10 [ 10.599434, 67.45303, 75.46433, 115.5706 ], 11 [101.44424, 137.79492, 165.17267, 201.09848 ], 12 [ 90.32121, 60.167862, 160.19128, 126.34792 ], 13 [ 92.46553, 210.28862, 167.8457, 296.00696 ]]) 14 15u, indices, inverse, counts = np.unique(out_classes, return_index = True, return_inverse = True, return_counts = True) 16 17if np.amax(counts)>=2:#---------------|重複があれば処理 18 print(out_classes) 19 print(u) 20 print(counts) 21 print("重複無し|", u[counts == 1])#|重複無しの要素 22 print("重複あり|", u[counts != 1])#|重複ありの要素 23 print(indices)#-------------------|該当数字が最初に出てくる場所 24 print(inverse) 25 26else: 27 print("重複無し")

補足情報(FW/ツールのバージョンなど)

python 3.8
numpy 1.18.0

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

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

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

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

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

guest

回答1

0

ベストアンサー

下記コードみたいな感じでどうでしょうか。groupbyを使いたいので途中pandasに頼ってやっています。

python

1import numpy as np 2import pandas as pd 3 4out_classes = np.array([0, 0, 3, 3, 5]) 5out_scores = np.array([0.99801666, 0.7711145, 0.9962558, 0.96635705, 0.80220133]) 6out_boxes = np.array( 7 [[ 8.540416, 61.232857, 76.36931, 123.20946 ], 8 [ 10.599434, 67.45303, 75.46433, 115.5706 ], 9 [101.44424, 137.79492, 165.17267, 201.09848 ], 10 [ 90.32121, 60.167862, 160.19128, 126.34792 ], 11 [ 92.46553, 210.28862, 167.8457, 296.00696 ]]) 12 13df = pd.DataFrame({"classes":out_classes, 14 "scores":out_scores}) 15idx = df.groupby("classes").idxmax()["scores"].values 16 17out_classes_ = out_classes[idx] 18out_scores_ = out_scores[idx] 19out_boxes_ = out_boxes[idx] 20print(repr(out_classes_)) 21print(repr(out_scores_)) 22print(repr(out_boxes_)) 23""" => 24array([0, 3, 5]) 25array([0.99801666, 0.9962558 , 0.80220133]) 26array([[ 8.540416, 61.232857, 76.36931 , 123.20946 ], 27 [101.44424 , 137.79492 , 165.17267 , 201.09848 ], 28 [ 92.46553 , 210.28862 , 167.8457 , 296.00696 ]]) 29"""

参考(pandasを使わない方法)

pandasに頼りたくない場合、pandasのgroupby相当のものがnumpyにも標準にもないので少し手間取ります。defaultdict(list)などを使うと比較的楽で、速度などの懸念もないかと思います。

python

1import numpy as np 2from operator import itemgetter 3from collections import defaultdict 4 5out_classes = np.array([0, 0, 3, 3, 5]) 6out_scores = np.array([0.99801666, 0.7711145, 0.9962558, 0.96635705, 0.80220133]) 7out_boxes = np.array( 8 [[ 8.540416, 61.232857, 76.36931, 123.20946 ], 9 [ 10.599434, 67.45303, 75.46433, 115.5706 ], 10 [101.44424, 137.79492, 165.17267, 201.09848 ], 11 [ 90.32121, 60.167862, 160.19128, 126.34792 ], 12 [ 92.46553, 210.28862, 167.8457, 296.00696 ]]) 13 14d = defaultdict(list) 15for i, c in enumerate(out_classes): 16 d[c].append((i, out_scores[i])) 17 18idx = [max(x, key=itemgetter(1))[0] for c, x in d.items()] 19 20# 例示用 21print(d) # defaultdict(<class 'list'>, {0: [(0, 0.99801666), (1, 0.7711145)], 3: [(2, 0.9962558), (3, 0.96635705)], 5: [(4, 0.80220133)]}) 22print(idx) # [0, 2, 4] 23 24# 以下はidxを用いて取り出すだけで、pandasを用いたコードと同じ

投稿2019/12/24 18:39

編集2019/12/24 18:57
hayataka2049

総合スコア30935

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

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

P5_USER

2019/12/25 00:44

hayataka2049さん 回答ありがとうございます。 辞書型にしてふるい落とす には目から鱗でした。 また、速度について気にかけていただいて、ありがたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問