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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python

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

配列

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

Q&A

解決済

3回答

1497閲覧

二次元配列から同値関係を計算したものを出力したい

ha_horse

総合スコア20

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python

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

配列

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

0グッド

0クリップ

投稿2020/06/15 10:16

編集2020/06/15 11:14

Pythonのプログラムにて、二次元配列から同値関係(単純に同じ列の値の数を足し合わせたもの)を計算したものを出力したいと考えております。

具体的には、

例えば動物データセット
||size|neck|color|
|:--|:--:|--:|
|Tiger|0|1|0
|Lion|0|0|2
|Cat|1|0|2
|Dog|0|0|0

▲表1

のようなデータセットから、
data = [[0,1,0],[0,0,2],[1,0,2],[0,0,0]] という二次元配列に格納したとします。

ここから同値関係を計算した正方行列を出力したいと考えてます。

出力したいものの具体的な計算方法

||Tiger|Lion|Cat|Dog|
|:--|:--:|--:|
|Tiger|0|1|0|2|
Lion|1|0|2|2
Cat|0|2|0|1
Dog|2|2|1|0

▲表2(weight_matrixと名付けます)

出力結果は上表になります。正方行列として捉えてください。こちらも同様に二次元配列。

具体的な計算方法としては、
表1の1行目と2行目の同列での同じ値はsizeの1つだけ。なのでweight_matrix[1][2]は1。
表1の1行目と3行目の同じ値は0個なのでwight_matrix[1][3]は0。
表1の1行目と4行目の同じ値はsizeとcolorの2つなのでweight_matrix[1][4]は2。

この計算作業を全ての行に対して行った結果が表2になります。

どなたかこの計算プログラムをご教授いただけないでしょうか。
やること自体は単純なのですが、forループでのdataのindex取得が上手くできません。


ご指摘をいただいたので、途中までのコードを載せます。

Python

1w_matrix = [] 2for i in range(len(data)): 3 cnt = 0 4 for j in range(len(data[i])): 5 temp_list = [] 6 if data[i][j] == data[i+j][j]: 7 cnt += 1 8 temp_list.append(cnt) 9 10 w_matrix.append(temp_list)

特に if data[i][j] == data[i+j][j]:
のインデックス参照部分がわかっておりません。
temp_list.append(cnt)の位置もおかしいです。

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

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

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

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

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

jeanbiego

2020/06/15 10:40

上手くいかなかったコードを、書けたところまで記載してください。その方が有用な回答が集まりますよ。
guest

回答3

0

アドバイスをするならば

  • 処理を分割して分かりやすくする
  • 無機質なijという変数よりも具体的な変数名を与える
  • w_matrixはtemp_list等を使って動的に作るよりも先に静的に作る

ということでしょうか。上記を意識した上で回答します。

最初に最終結果となる4x4の行列であるw_matrixを作ります。

python

1w_matrix = [[0 for animal2 in range(4)] for animal1 in range(4)]

こうしておく事でw_matrix[animal1][animal2] = cntとして代入が可能になります。

次に(Tiger, Lion, Cat, Dog)の4つの中から2つ選ぶというルーチンを作成します。

python

1for animal1 in range(4): 2 for animal2 in range(animal1 + 1, 4): 3 print(animal1, animal2)

ここでanimal1animal2は行列要素の行に対するインデックスになります。
次にanimal1とanimal2の比較して同値のカウントを行う処理を書きます。

python

1cnt = 0 2for feature in range(3): 3 if data[animal1][feature] == data[animal2][feature]: 4 cnt += 1 5w_matrix[animal1][animal2] = cnt 6w_matrix[animal2][animal1] = cnt

この処理を2つ目のソースコードのprint()部分に埋め込めば良いです。

実装例

上記とは別に、参考までに私の実装例を示します。

python

1from itertools import combinations 2import pandas as pd 3import numpy as np 4 5# 設問のデータフレームを準備 6df = pd.DataFrame( 7 {"size": [0, 0, 1, 0], "neck": [1, 0, 0, 0], "color": [0, 2, 2, 0],}, 8 index=["Tiger", "Lion", "Cat", "Dog"], 9) 10print(df) 11 12# 同値関係のデータフレームを作成 13df_equ = pd.DataFrame( 14 np.zeros(shape=(len(df), len(df)), dtype=int), 15 index=df.index, 16 columns=df.index, 17) 18for pair in combinations(df.index, 2): 19 comp = df.loc[pair[0]] - df.loc[pair[1]] 20 equal_count = (comp == 0).sum() 21 df_equ.loc[pair[0], pair[1]] = equal_count 22 df_equ.loc[pair[1], pair[0]] = equal_count 23 24print(df_equ)

以下、結果になります。

terminal

1$ python equ.py 2 size neck color 3Tiger 0 1 0 4Lion 0 0 2 5Cat 1 0 2 6Dog 0 0 0 7 Tiger Lion Cat Dog 8Tiger 0 1 0 2 9Lion 1 0 2 2 10Cat 0 2 0 1 11Dog 2 2 1 0

投稿2020/06/15 11:53

編集2020/06/15 11:57
yymmt

総合スコア1615

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

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

ha_horse

2020/06/15 12:07

ご回答ありがとうございます。参考にさせていただきます。コードに関するアドバイスもいただき、本当にありがとうございます。
guest

0

質問でやろうとしていることは、2つのサンプルを x = (x1, x2, x3), y = (y1, y2, y3) としたとき、一致する成分の数を距離と定義して、各サンプル間の距離を計算した距離行列を作成することにほかなりません。

python

1tiger = np.array([0, 1, 0]) 2lion = np.array([0, 0, 2]) 3 4print(tiger == lion) 5# [ True False False] 6 7# True は1、False は0と同値なので、和をとると一致する要素数になる 8dist = (tiger == lion).sum() 9print(dist) # 1

サンプルコード

なので、以下のように距離行列を作成すれば、求めている行列が得られます。
自身との比較はすべて一致するので、上記定義に従えば3となるはずですが、0としたいのであれば、あとから対角成分を0で埋めてください。

python

1import numpy as np 2import pandas as pd 3 4df = pd.DataFrame( 5 {"size": [0, 0, 1, 0], "neck": [1, 0, 0, 0], "color": [0, 2, 2, 0]}, 6 index=["Tiger", "Lion", "Cat", "Dog"], 7) 8print(df) 9# size neck color 10# Tiger 0 1 0 11# Lion 0 0 2 12# Cat 1 0 2 13# Dog 0 0 0 14 15# 距離行列を計算する 16# 形状が (サンプル数, 1, 特徴量の数) の配列と形状が (サンプル数, 特徴量の数) の配列で比較すると、 17# ブロードキャストされて (サンプル数, サンプル数, 特徴量の数) の配列同士の比較になる 18dist_matrix = (df.values[:, np.newaxis] == df.values).sum(axis=-1) 19np.fill_diagonal(dist_matrix, 0) # 主対角成分を0でうめる 20 21dist_matrix = pd.DataFrame(dist_matrix, index=df.index, columns=df.index) 22print(dist_matrix) 23# Tiger Lion Cat Dog 24# Tiger 0 1 0 2 25# Lion 1 0 2 2 26# Cat 0 2 0 1 27# Dog 2 2 1 0

投稿2020/06/15 11:49

編集2020/06/15 11:51
tiitoi

総合スコア21956

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

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

ha_horse

2020/06/15 12:07

ご回答ありがとうございます。参考にさせていただきます。周辺知識までご教授いただき、本当にありがとうございます。
guest

0

自己解決

こちらの三重ループで解決しました。ありがとうございました。

data = [[0,1,0],[0,0,2],[1,0,2],[0,0,0]] w_matrix = [] for i in range(len(data)): temp_list = [] for j in range(len(data)): cnt = 0 for k in range(len(data[i])): print(k) if data[i][k] == data[j][k] and i != j: cnt += 1 temp_list.append(cnt) print(temp_list) w_matrix.append(temp_list) print(w_matrix)

投稿2020/06/15 11:49

ha_horse

総合スコア20

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問