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

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

新規登録して質問してみよう
ただいま回答率
85.37%
NumPy

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

Python

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

1464閲覧

numpy配列から複数条件で値を検索し、指定のデータ数を抜き出して新しい行列を生成する

goma-goma

総合スコア39

NumPy

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

Python

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/04/20 13:25

画像にあるような1列のnumpy配列の中から13と10が連続して続く箇所を検索し、その次から8個分のデータを抜き出して別の変数に格納する方法を教えていただきたいです。(それを配列が終わるまで繰り返して抜き出した8つのデータを1列とした行列を作りたい)
numpy配列の中からある値とある値が連続している箇所を検索する、というところから躓いておりなかなか前に進めない状況です、、

ざっくりとした質問で申し訳ありませんが、どなたか教えていただけると助かります。

イメージ説明

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

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

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

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

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

guest

回答2

0

Numpyには便利なベクトル化された関数・メソッドがたくさん実装されています。
ベクトル化された関数・メソッドを用いることで、Python標準のfor文を用いるよりも効率よく処理することができます。

python

1def extract(arr, v, n): 2 """ 3 arr : 検索元の配列(1次元ndarray) 4 v: 検索する配列(1次元のarray-like) 5 n: 取り出す個数(int) 6 """ 7 vln = len(v) 8 base = (arr.max()+1) ** np.arange(vln) 9 search_idx, = np.nonzero(np.convolve(arr, base) == np.sum(base*v[::-1])) 10 idx = search_idx + np.arange(1, n+1)[:, None] 11 return arr[idx]

python

1# 実行例 2In [11]: rn = np.random.RandomState(0) 3 ...: arr = rn.randint(0, 100, 100000) 4 ...: extract(arr, [13, 10], 8) 5Out[11]: 6array([[60, 80, 13, 98, 80, 72, 25, 10, 21, 0], 7 [61, 21, 10, 57, 80, 81, 68, 12, 19, 53], 8 [21, 84, 98, 45, 74, 23, 74, 95, 55, 35], 9 [48, 80, 57, 30, 32, 27, 36, 76, 27, 79], 10 [87, 36, 45, 85, 51, 51, 88, 70, 22, 5], 11 [76, 51, 30, 45, 33, 78, 94, 55, 20, 84], 12 [35, 49, 85, 35, 49, 20, 21, 88, 82, 0], 13 [93, 16, 45, 68, 55, 23, 1, 25, 35, 21]]) 14 15# @aokikenichi さんの作成した配列に対して 16In [12]: l = [0, 1, 2, 3, 17 ...: 13, 10, 5, 4, 3, 2, 1, 0, 18 ...: 13, 10, 1, 2, 3, 4, 5, 6, 7, 19 ...: 13, 10, 99, 98, 97, 96, 95, 94, 20 ...: 13, 10, 100, 101, 102, 103, 104, 105] 21 ...: extract(np.array(l), [13, 10], 3) 22Out[12]: 23array([[ 5, 1, 99, 100], 24 [ 4, 2, 98, 101], 25 [ 3, 3, 97, 102]]) 26 27# 条件を変えることもできます 28In [13]: extract(np.array(l), [1, 2, 3], 4) 29Out[13]: 30array([[13, 4], 31 [10, 5], 32 [ 5, 6], 33 [ 4, 7]])

@aokikenichi さんの回答は一般化すると以下のような関数になりますが、

python

1def extract_for(l, v, n): 2 vln = len(v) 3 out = [] 4 for i in range(len(l) - 1): 5 if all(l[i+j] == vi for j, vi in enumerate(v)): 6 out.append(l[i+vln:i+vln+n]) 7 return np.array(out).T

速度を比較するとNumpyの関数を用いたほうが効率が良いことがわかります。

python

1# arrは長さ100000の配列 2In [21]: %timeit extract(arr, [13, 10], 8) 3698 µs ± 15.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 4 5In [22]: l = arr.tolist() 6 ...: %timeit extract_for(l, [13, 10], 8) 778 ms ± 1.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

投稿2021/04/21 04:07

編集2021/04/21 07:16
kirara0048

総合スコア1399

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

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

0

ベストアンサー

Python

1l = [0, 1, 2, 3, 13, 10, 5, 4, 3, 2, 1, 0, 13, 10, 1, 2, 3, 4, 5, 6, 7, 13, 10, 99, 98, 97, 96, 95, 94, 13, 10, 100, 101, 102, 103, 104, 105] 2 3out = [] 4for i in range(len(l) - 1): 5 if l[i] == 13 and l[i + 1] == 10: 6 out.append(l[i + 2]) 7 out.append(l[i + 3]) 8 out.append(l[i + 4]) 9print(out)
[5, 4, 3, 1, 2, 3, 99, 98, 97, 100, 101, 102]

入力リストを作るのが面倒なので適当に作成し、8個先までではなくて3個先までにしました。

1列とした行列を作りたい

だが例示されたものは3列の行列 なところが分かりませんが 大体こんな感じでは無いですか?

投稿2021/04/20 13:43

aokikenichi

総合スコア2235

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

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

goma-goma

2021/04/20 13:54

ありがとうございます! 非常に助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問