Skip to content

Instantly share code, notes, and snippets.

@KatsuhiroMorishita
Last active April 23, 2018 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KatsuhiroMorishita/403a4e2e03f3c6b17eb86db53c981749 to your computer and use it in GitHub Desktop.
Save KatsuhiroMorishita/403a4e2e03f3c6b17eb86db53c981749 to your computer and use it in GitHub Desktop.
文字列やベクトルや行列を含む配列の一致を判定する関数です。Pythonで行った数値計算の試験の解答用に開発しました。
# 不定形のベクトルの一致を判定する
# 数値計算の試験の解答用に開発した。
# author: Katsuhiro Morishita
# created: 2018-02
# lisence: MIT
import numpy as np
import collections
def flatten(foo):
""" 多次元配列を1次元配列に変換する
setや辞書には対応していない。
"""
if isinstance(foo, np.matrixlib.defmatrix.matrix): # matrixはndarrayに変換しておかないと、中身を取り出せない
foo = np.array(foo)
series = []
for mem in foo:
if isinstance(mem, collections.Iterable) and not isinstance(mem, str):
bar = flatten(mem)
series += bar
elif isinstance(mem, complex):
series.append(mem.real)
series.append(mem.imag)
else:
#print(mem)
series.append(mem)
return series
def check(o, t, th=0.001):
""" 2つのベクトルの中身が数値計算的に等しいかどうか確認する
return
True: 等しい
False: 等しくない
"""
# 入れ子構造の変数を1次元に変換
o = flatten([o])
t = flatten([t])
# 次元数の確認
if len(o) != len(t):
print("--0--, length not match")
return False
# intをfloatに変更
_o = [float(x) if isinstance(x, int) else x for x in o]
_t = [float(y) if isinstance(y, int) else y for y in t]
_o = [float(x) if isinstance(x, np.int16) else x for x in _o]
_t = [float(y) if isinstance(y, np.int16) else y for y in _t]
_o = [float(x) if isinstance(x, np.int32) else x for x in _o]
_t = [float(y) if isinstance(y, np.int32) else y for y in _t]
_o = [float(x) if isinstance(x, np.int64) else x for x in _o]
_t = [float(y) if isinstance(y, np.int64) else y for y in _t]
_o = [float(x) if isinstance(x, np.float32) else x for x in _o]
_t = [float(y) if isinstance(y, np.float32) else y for y in _t]
_o = [float(x) if isinstance(x, np.float64) else x for x in _o]
_t = [float(y) if isinstance(y, np.float64) else y for y in _t]
# 型をチェック 一方がNoneでもFalseとなる
c = [type(x) == type(y) for x,y in zip(_o, _t)]
if False in c:
print("--1--")
print(_o, _t, c)
return False
# 完全一致だとTrue NoneでもOK 数値は処理したくない
__o = [True if x == y or x is y else x for x,y in zip(_o, _t)] # 文字列の一致もここでチェックできる
__t = [True if x == y or x is y else y for x,y in zip(_o, _t)]
# 文字列の不一致を数値化
_o = [0 if isinstance(x, str) else x for x,y in zip(__o, __t)] # 文字角不一致があれば、それを0と1(ベクトル的には直交)で表現する
_t = [1 if isinstance(x, str) else y for x,y in zip(__o, __t)]
#print("--2--", _o, _t)
# ベクトル内の数値の要素を個別にチェック(Trueは1、Falseは0として扱われる)
for i in range(len(_o)): # 0での除算を避けるための処理
x, y = _o[i], _t[i]
m = max(x, y)
if m == 0.0:
_o[i] = 0.0000001
ans = [abs((x - y) / max(x, y)) < th for x,y in zip(_o, _t)]
print("--3--", ans)
return False not in ans
def main():
a = [10.1, "解なし", False, [10, "解なし", 45, [10, 20, 30]]]
#a = [10.1, "解なし", False, [10, 0.001, 45, [10, 20, 10+3j]]]
b = [10.11, "解なし", False, [10, 0.001, 45, [10, 20, 10+3j]]]
#b = [10, "解あり", True, [10, 20, 30, [10, 20, 30-23j]]]
print(check(a, b))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment