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

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

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

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

Python 3.x

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

Python

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

配列

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

Q&A

3回答

575閲覧

nparrayの配列(ex:[1 0 3 0 0])の0を一つ3にしたときに一致する配列(ex:[1 3 3 0 0])をリストの中から探す。

Ralutet

総合スコア0

NumPy

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

Python 3.x

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

Python

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

配列

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

0グッド

0クリップ

投稿2021/12/28 08:59

編集2021/12/28 09:05

前提・実現したいこと

[[0 1 3 3 0]
[1 0 3 0 0]
[1 0 3 3 0]
[1 3 3 0 0]
[1 3 0 0 0]]
というnparrayの配列についてです。1つ目([1 0 3 0 0])の0のいずれか1箇所に3を追加すると2つ目([1 0 3 3 0])、3つ目([1 3 3 0 0])になります。なので、[2 3 0]と出力させたいです。それを0つ目から4つ目まで全て行い、それをまた別のnparrayの配列に出力させたいです。つまり、
[[0 0 0]
[2 3 0]
[0 0 0]
[0 0 0]
[3 0 0]]
という配列を出力させたいです。
以下のコードで実現はできるのですが、速度があまり早くありません。実際はこの配列の要素はもっと多いのであまり時間がかかりすぎると少々不都合がありまして。。

書いたコード(print抜)

Python

1import numpy as np 2lst = np.array([[0,1,3,3,0],[1,0,3,0,0],[1,0,3,3,0],[1,3,3,0,0],[1,3,0,0,0]])#質問の一番上に書いてる配列と同じ 3lst2 = np.zeros((10,3))#後に、質問の上から二番目に書いてる配列と同じになる 4for i in range(len(lst)):#0つ目から試す(3にする前のもの) 5 lst2_temp = [] 6 for j in range(len(lst)):#0つ目から試す(3にした後のもの) 7 if int(np.count_nonzero(lst[j] > 0)) - int(np.count_nonzero(lst[i] > 0)) == 1:#それらの配列の0の数が一つ違う = 3が一つ増えた 8 if np.count_nonzero(np.logical_and(lst[j]-lst[i] != 3, lst[j]-lst[i] != 0)) == 0:#それらの配列の差をとったときに、3でも0でもないところがない = 3が一つ増えた以外の変化はない 9 lst2_temp.append(j) #3にしたあとのものの番号を記録する 10 for j in range(len(lst2[0])-len(lst2_temp)):#リストの長さを3に調整するためのもの 11 lst2_temp.append(0) 12 lst2[i] = np.array(lst2_temp)#これで、質問の上から二番目に書いてる配列と同じになる

書いたコード(print込)

Python

1import numpy as np 2lst = np.array([[0,1,3,3,0],[1,0,3,0,0],[1,0,3,3,0],[1,3,3,0,0],[1,3,0,0,0]])#質問の一番上に書いてる配列と同じ 3lst2 = np.zeros((10,3))#後に、質問の上から二番目に書いてる配列と同じになる 4print(lst) 5for i in range(len(lst)):#0つ目から試す(3にする前のもの) 6 lst2_temp = [] 7 print() 8 print("i:",lst[i]) 9 for j in range(len(lst)):#0つ目から試す(3にした後のもの) 10 print("j:",lst[j]) 11 print("i_num:",np.count_nonzero(lst[i] > 0)) 12 print("j_num:",np.count_nonzero(lst[j] > 0)) 13 if int(np.count_nonzero(lst[j] > 0)) - int(np.count_nonzero(lst[i] > 0)) == 1:#それらの配列の0の数が一つ違う = 3が一つ増えた 14 print(lst[j]-lst[i]) 15 if np.count_nonzero(np.logical_and(lst[j]-lst[i] != 3, lst[j]-lst[i] != 0)) == 0:#それらの配列の差をとったときに、3でも0でもないところがない = 3が一つ増えた以外の変化はない 16 print(j) 17 lst2_temp.append(j)#3にしたあとのものの番号を記録する 18 for j in range(len(lst2[0])-len(lst2_temp)):#リストの長さを3に調整するためのもの 19 lst2_temp.append(0) 20 print("lst2_temp:",lst2_temp) 21 lst2[i] = np.array(lst2_temp)#これで、質問の上から二番目に書いてる配列と同じになる 22print(lst2)

出力されたもの

[[0 1 3 3 0] [1 0 3 0 0] [1 0 3 3 0] [1 3 3 0 0] [1 3 0 0 0]] i: [0 1 3 3 0] j: [0 1 3 3 0] i_num: 3 j_num: 3 j: [1 0 3 0 0] i_num: 3 j_num: 2 j: [1 0 3 3 0] i_num: 3 j_num: 3 j: [1 3 3 0 0] i_num: 3 j_num: 3 j: [1 3 0 0 0] i_num: 3 j_num: 2 lst2_temp: [0, 0, 0] i: [1 0 3 0 0] j: [0 1 3 3 0] i_num: 2 j_num: 3 [-1 1 0 3 0] j: [1 0 3 0 0] i_num: 2 j_num: 2 j: [1 0 3 3 0] i_num: 2 j_num: 3 [0 0 0 3 0] 2 j: [1 3 3 0 0] i_num: 2 j_num: 3 [0 3 0 0 0] 3 j: [1 3 0 0 0] i_num: 2 j_num: 2 lst2_temp: [2, 3, 0] i: [1 0 3 3 0] j: [0 1 3 3 0] i_num: 3 j_num: 3 j: [1 0 3 0 0] i_num: 3 j_num: 2 j: [1 0 3 3 0] i_num: 3 j_num: 3 j: [1 3 3 0 0] i_num: 3 j_num: 3 j: [1 3 0 0 0] i_num: 3 j_num: 2 lst2_temp: [0, 0, 0] i: [1 3 3 0 0] j: [0 1 3 3 0] i_num: 3 j_num: 3 j: [1 0 3 0 0] i_num: 3 j_num: 2 j: [1 0 3 3 0] i_num: 3 j_num: 3 j: [1 3 3 0 0] i_num: 3 j_num: 3 j: [1 3 0 0 0] i_num: 3 j_num: 2 lst2_temp: [0, 0, 0] i: [1 3 0 0 0] j: [0 1 3 3 0] i_num: 2 j_num: 3 [-1 -2 3 3 0] j: [1 0 3 0 0] i_num: 2 j_num: 2 j: [1 0 3 3 0] i_num: 2 j_num: 3 [ 0 -3 3 3 0] j: [1 3 3 0 0] i_num: 2 j_num: 3 [0 0 3 0 0] 3 j: [1 3 0 0 0] i_num: 2 j_num: 2 lst2_temp: [3, 0, 0] [[0. 0. 0.] [2. 3. 0.] [0. 0. 0.] [0. 0. 0.] [3. 0. 0.]]

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

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

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

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

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

guest

回答3

0

0を一箇所3に変更して同じになるということは、行同士で値ごとの差をとると[0 0 0 0 3]を並び替えたものになるということです。
このことを利用すればfor文を使わなくてもベクトルアプローチで求めることができます。
(また、当然ですが、今回は配列の値に0,3,1しか使われていませんので問題ありませんが、もし3 - 0 = 3以外で差が3になる組み合わせがある場合は数を変更してください)

python

1lst = np.array([[0, 1, 3, 3, 0], 2 [1, 0, 3, 0, 0], 3 [1, 0, 3, 3, 0], 4 [1, 3, 3, 0, 0], 5 [1, 3, 0, 0, 0]]) 6 7tmp_ar = lst - lst[:, None, :] 8result = ((tmp_ar == 3).sum(-1) == 1) & ((tmp_ar == 0).sum(-1) == 4) 9 10 11# 出力例(質問にある出力結果の意味がわからなかったので適宜修正してください) 12for i, row in enumerate(result): 13 print(i, np.flatnonzero(row)) 14# 0 [] 15# 1 [2 3] 16# 2 [] 17# 3 [] 18# 4 [3]

投稿2022/01/05 02:15

kirara0048

総合スコア1399

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

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

0

内包表記が速いのでは?

Python

1pre = 0 2post = 3 3lst = [[0,1,3,3,0],[1,0,3,0,0],[1,0,3,3,0],[1,3,3,0,0],[1,3,0,0,0]] 4ans = [[j for j,ls1 in enumerate(lst) for k in range(len(lst[0])) 5 if ls0[k] == pre and ls1[k] == post 6 and ls0[:k] == ls1[:k] and ls0[k+1:] == ls1[k+1:]] 7 for ls0 in lst] 8ans = [s + [0]*(3-len(s)) for s in ans] 9print(ans) # [[0, 0, 0], [2, 3, 0], [0, 0, 0], [0, 0, 0], [3, 0, 0]]

投稿2021/12/28 14:58

lehshell

総合スコア1156

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

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

0

ご質問のコードを実行したところ以下となりました。

python

1>>> import numpy as np 2>>> lst = np.array([[0,1,3,3,0],[1,0,3,0,0],[1,0,3,3,0],[1,3,3,0,0],[1,3,0,0,0]])#質問の一番上に書いてる配列と同じ 3>>> lst2 = np.zeros((10,3))#後に、質問の上から二番目に書いてる配列と同じになる 4>>> for i in range(len(lst)):#0つ目から試す(3にする前のもの) 5... lst2_temp = [] 6... for j in range(len(lst)):#0つ目から試す(3にした後のもの) 7... if int(np.count_nonzero(lst[j] > 0)) - int(np.count_nonzero(lst[i] > 0)) == 1:#それらの配列の0の数が一つ違う = 3が一つ増えた 8... if np.count_nonzero(np.logical_and(lst[j]-lst[i] != 3, lst[j]-lst[i] != 0)) == 0:#それらの配列の差をとったときに、3でも0でもないところがない = 3が一つ増えた以外の変化はない 9... lst2_temp.append(j) #3にしたあとのものの番号を記録する 10... for j in range(len(lst2[0])-len(lst2_temp)):#リストの長さを3に調整するためのもの 11... lst2_temp.append(0) 12... lst2[i] = np.array(lst2_temp)#これで、質問の上から二番目に書いてる配列と同じになる 13... 14>>> lst2 15array([[0., 0., 0.], 16 [2., 3., 0.], 17 [0., 0., 0.], 18 [0., 0., 0.], 19 [3., 0., 0.], 20 [0., 0., 0.], 21 [0., 0., 0.], 22 [0., 0., 0.], 23 [0., 0., 0.], 24 [0., 0., 0.]])

提示された出力と異なっています。

また、

python

1lst = np.array([[0,0,0,0,0],[3,0,0,0,0],[0,3,0,0,0],[0,0,3,0,0],[0,0,0,3,0]])

で実行すると、以下のようなエラーになります。

python

1Traceback (most recent call last): 2 File "<stdin>", line 9, in <module> 3ValueError: could not broadcast input array from shape (4,) into shape (3,)

これは5×3行列や5×3行列では表現できないからです。

求める組み合わせを抽出したいだけであれば以下で可能です。

python

1import numpy as np 2before = 0 3after = 3 4lst = np.array([[0,1,3,3,0],[1,0,3,0,0],[1,0,3,3,0],[1,3,3,0,0],[1,3,0,0,0]]) 5 6rows = lst.shape[0] 7for i in range(rows): 8 for j in range(rows): 9 diff = np.where(lst[i]!=lst[j])[0] 10 if len(diff) == 1 and lst[i,diff[0]] == before and lst[j,diff[0]] == after: 11 print(i, j, diff)

実行結果

python

1>>> import numpy as np 2>>> before = 0 3>>> after = 3 4>>> lst = np.array([[0,1,3,3,0],[1,0,3,0,0],[1,0,3,3,0],[1,3,3,0,0],[1,3,0,0,0]]) 5>>> 6>>> rows = lst.shape[0] 7>>> for i in range(rows): 8... for j in range(rows): 9... diff = np.where(lst[i]!=lst[j])[0] 10... if len(diff) == 1 and lst[i,diff[0]] == before and lst[j,diff[0]] == after: 11... print(i, j, diff) 12... 131 2 [3] 141 3 [1] 154 3 [2]

投稿2021/12/28 13:02

ppaul

総合スコア24670

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問