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

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

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

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

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

1079閲覧

python 数値配列に別の配列要素で書き換えたい

macchairi

総合スコア13

NumPy

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

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2019/06/30 06:37

編集2019/06/30 08:10

前提・実現したいこと

python(3系)を使って数値配列を操作しています。
n行×3列の3次元配列A, Bがあったとして、
1,2列目が完全一致する行だけ、Aの3列目要素でBの3列目要素を書き換えたいのです。

発生している問題・エラーメッセージ

python

1while (A[i, 0] == list(B[:, 0])) and (A[i, 1] == list(B[:, 1])): 2 a = B.replace(B[:, 2], A[i, 2])

上記のような条件で色々な構文を試したのですが、エラーが出なくとも思うように置換できません。配列は、数値配列です。下のような配列で列1, 2がともに一致したものだけ列3の数値を置換することをしたいです。

|列1|列2|列3|
|1|1|3|
|1|2|5|
|1|3|4|

よろしくお願いします。

[追記]
具体的には、2次元グリッドの等高線を描くために、ダミーのプロット点(B)に対してAから一部置換することを目的としています。たとえば、以下のA, Bのようなものを想定しています。

A:
|列1|列2|列3|
|0|0|3|
|0|2|5|
|2|1|4|

B:
|列1|列2|列3|
|0|0|1|
|0|1|1|
|0|2|1|
|1|0|1|
|1|1|1|
|1|2|1|
|2|0|1|
|2|1|1|
|2|2|1|

該当のソースコード

ソースコード

試したこと

ここに問題に対して試したことを記載してください。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

r_takahama

2019/06/30 06:47

A, B の行数は同じですか? 可能であれば、AとBのより具体的な例を追記していただけませんか?
macchairi

2019/06/30 08:11

回答ありがとうございます。 情報を追記させていただきました。 AよりもBの行数は多い状況になります。
r_takahama

2019/06/30 08:23

承知しました。回答いたします!
guest

回答2

0

要件をお伺いするに、たくさんのデータ点を同時に処理したいという状況であるようにお見受けいたしました。こうした場合は、もし可能であればpandasを使うのがもっとも楽かと思います。(そうでない場合はhayataka2049様の回答が参考になるかと思いますので、pandasを使わない回答は省略します)

詳細

pandasをimportします。

python

1import pandas as pd

Aと、Aの情報を格納したpandasのDataFrameを作ります。

python

1A = [ 2 [0, 0, 3], 3 [0, 2, 5], 4 [2, 1, 4], 5] 6df_A = pd.DataFrame(A, columns=['x', 'y', 'h']) 7print(df_A)

print文の出力は以下のようになります。

sh

1 x y h 20 0 0 3 31 0 2 5 42 2 1 4

Bに関しても同様にDataFrameを作ります。

python

1B = [ 2 [0, 0, 1], 3 [0, 1, 1], 4 [0, 2, 1], 5 [1, 0, 1], 6 [1, 1, 1], 7 [1, 2, 1], 8 [2, 0, 1], 9 [2, 1, 1], 10 [2, 2, 1], 11] 12df_B = pd.DataFrame(B, columns=['x', 'y', 'h']) 13print(df_B)

print文の出力は以下のようになります。

sh

1 x y h 20 0 0 1 31 0 1 1 42 0 2 1 53 1 0 1 64 1 1 1 75 1 2 1 86 2 0 1 97 2 1 1 108 2 2 1

df_Adf_B をマージします。感覚的には、 df_B に対して、 x と 'y' が一致する行を df_A からうまく選んで右側にくっつける感じです。

python

1df_merged = pd.merge(df_B, df_A, how='left', on=['x', 'y']) 2print(df_merged)

print文の出力は以下のようになります。

sh

1 x y h_x h_y 20 0 0 1 3.0 31 0 1 1 NaN 42 0 2 1 5.0 53 1 0 1 NaN 64 1 1 1 NaN 75 1 2 1 NaN 86 2 0 1 NaN 97 2 1 1 4.0 108 2 2 1 NaN

df_mergedh_y を使いたいですが、 df_A に値が存在しなかった 'x', 'y' についてはNaNになってしまっているため、ダミーの値で h_y を埋めます。

python

1dummy_value = 1 2df_filled = df_merged.fillna(dummy_value) 3print(df_filled)

print文の出力は以下のようになります。

x y h_x h_y 0 0 0 1 3.0 1 0 1 1 1.0 2 0 2 1 5.0 3 1 0 1 1.0 4 1 1 1 1.0 5 1 2 1 1.0 6 2 0 1 1.0 7 2 1 1 4.0 8 2 2 1 1.0

最後に、 x, y, h_y のみを残せば、所望の値が得られると思います。
df_result = df_filled[['x', 'y', 'h_y']]
print(df_result)

print文の出力は以下のようになります。

python

1 x y h_y 20 0 0 3.0 31 0 1 1.0 42 0 2 5.0 53 1 0 1.0 64 1 1 1.0 75 1 2 1.0 86 2 0 1.0 97 2 1 4.0 108 2 2 1.0

なお、

python

1df_result.values

を呼び出すと、 pd.DataFrame から np.ndarray 形式のデータに変換することもできます。

コード全文

python

1import pandas as pd 2 3A = [ 4 [0, 0, 3], 5 [0, 2, 5], 6 [2, 1, 4], 7] 8df_A = pd.DataFrame(A, columns=['x', 'y', 'h']) 9print(df_A) 10 11B = [ 12 [0, 0, 1], 13 [0, 1, 1], 14 [0, 2, 1], 15 [1, 0, 1], 16 [1, 1, 1], 17 [1, 2, 1], 18 [2, 0, 1], 19 [2, 1, 1], 20 [2, 2, 1], 21] 22df_B = pd.DataFrame(B, columns=['x', 'y', 'h']) 23print(df_B) 24 25df_merged = pd.merge(df_B, df_A, how='left', on=['x', 'y']) 26print(df_merged) 27 28dummy_value = 1 29df_filled = df_merged.fillna(dummy_value) 30print(df_filled) 31 32df_result = df_filled[['x', 'y', 'h_y']] 33print(df_result)

投稿2019/06/30 08:37

r_takahama

総合スコア106

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

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

macchairi

2019/06/30 15:24

丁寧な回答どうもありがとうございます。 頂いたコード、勉強活用させて頂きます。 おっしゃる通りで、いずれ大規模なデータのハンドリングも目指していました。次元数が増えたときにはpandasが扱いやすいように思いました。 どうもありがとうございました。
guest

0

ベストアンサー

0列目と1列目を抜き出した部分配列同士を比較してから(同じshapeのbool配列が返ります)、allメソッドで「0列目と1列目がともにTrue」かどうかを計算して、それに基づいて代入を行います。

python

1import numpy as np 2 3A = np.array([[0, 0, 1], 4 [1, 2, 3], 5 [0, 2, 3], 6 [4, 1, 5]]) 7 8B = np.array([[0, 0, 5], 9 [3, 2, 1], 10 [0, 2, 6], 11 [2, 5, 7]]) 12 13idx = (A[:, 0:2] == B[:, 0:2]).all(axis=1) 14B[idx, 2] = A[idx, 2] 15print(B) 16""" 17[[0 0 1] 18 [3 2 1] 19 [0 2 3] 20 [2 5 7]] 21"""
追記に関して

安直なのはループですかね。

python

1import numpy as np 2 3A = np.array([[0, 0, 3], 4 [0, 2, 5], 5 [2, 1, 4]]) 6 7B = np.array([[0, 0, 1], 8 [0, 1, 1], 9 [0, 2, 1], 10 [1, 0, 1], 11 [1, 1, 1], 12 [1, 2, 1], 13 [2, 0, 1], 14 [2, 1, 1], 15 [2, 2, 1]]) 16 17for a in A: 18 idx = (B[:,0:2] == a[0:2]).all(axis=1) 19 B[idx, 2] = a[2] 20print(B) 21 22""" 23[[0 0 3] 24 [0 1 1] 25 [0 2 5] 26 [1 0 1] 27 [1 1 1] 28 [1 2 1] 29 [2 0 1] 30 [2 1 4] 31 [2 2 1]] 32"""

投稿2019/06/30 07:45

編集2019/06/30 08:22
hayataka2049

総合スコア30933

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

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

macchairi

2019/06/30 08:14

回答いただきありがとうございます。 .allや.anyの使い方、わかっていなかったので勉強になります。 情報追記させて頂いたのですが、arrayの行の数がAとBで異なる場合はどのようにすればよいでしょうか。 お時間ありましたら教えていただけると助かります。
hayataka2049

2019/06/30 08:23

追記してみました。こういう要件で合っていますか?
macchairi

2019/06/30 08:30

まさにそのような処理を目的としていました。 どうもありがとうございます。非常に助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問