現在、リストとして表された vector3 値があります。vector3 値のように、これらの 2 つを減算する方法はありますか?
[2,2,2] - [1,1,1] = [1,1,1]
タプルを使用する必要がありますか?
それらのいずれもこれらの型でこれらのオペランドを定義していない場合、代わりに定義できますか?
そうでない場合、新しい vector3 クラスを作成する必要がありますか?
これが頻繁に行うことになり、さまざまな操作を行う場合は、このようなケースを処理するクラスを作成するか、Numpyなどのライブラリを使用することをお勧めします。
それ以外の場合は、 zip組み込み関数で使用されるリスト内包表記を探します。
[a_i - b_i for a_i, b_i in zip(a, b)]
リスト内包表記に代わるものを次に示します。Map はリスト (後者の引数) を同時に繰り返し処理し、それらの要素を引数として関数に渡します (最初の引数)。結果のリストを返します。
import operator
map(operator.sub, a, b)
このコードは構文が少ないため (私にとっては美的です)、長さ 5 のリストの場合は明らかに 40% 高速です (bobince のコメントを参照)。それでも、どちらのソリューションも機能します。
リストが a と b の場合、次のことができます。
map(int.__sub__, a, b)
しかし、おそらくそうすべきではありません。それが何を意味するのかは誰にもわかりません。
NumPyもお勧めします
ベクトル計算が高速であるだけでなく、便利な関数がたくさんあります。
1d ベクトルでさらに高速なものが必要な場合は、vopを試してください
MatLab に似ていますが、無料です。これがあなたがすることの例です
from numpy import matrix
a = matrix((2,2,2))
b = matrix((1,1,1))
ret = a - b
print ret
>> [[1 1 1]]
ブーム。
「a」と「b」という 2 つのリストがある場合、次のことができます。[m - n for m,n in zip(a,b)]
わずかに異なるVectorクラス。
class Vector( object ):
def __init__(self, *data):
self.data = data
def __repr__(self):
return repr(self.data)
def __add__(self, other):
return tuple( (a+b for a,b in zip(self.data, other.data) ) )
def __sub__(self, other):
return tuple( (a-b for a,b in zip(self.data, other.data) ) )
Vector(1, 2, 3) - Vector(1, 1, 1)
複数の単純なライナーを実行する予定がある場合は、独自のクラスを実装し、ケースに適用される適切な演算子をオーバーライドすることをお勧めします。
Python の数学から引用:
class Vector:
def __init__(self, data):
self.data = data
def __repr__(self):
return repr(self.data)
def __add__(self, other):
data = []
for j in range(len(self.data)):
data.append(self.data[j] + other.data[j])
return Vector(data)
x = Vector([1, 2, 3])
print x + x
多くの解決策が提案されています。
速度に関心がある場合は、速度に関するさまざまなソリューションのレビューを次に示します (最速から低速まで)。
import timeit
import operator
a = [2,2,2]
b = [1,1,1] # we want to obtain c = [2,2,2] - [1,1,1] = [1,1,1
%timeit map(operator.sub, a, b)
176 ns ± 7.18 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit map(int.__sub__, a, b)
179 ns ± 4.95 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit map(lambda x,y: x-y, a,b)
189 ns ± 8.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [a_i - b_i for a_i, b_i in zip(a, b)]
421 ns ± 18.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [x - b[i] for i, x in enumerate(a)]
452 ns ± 17.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each
%timeit [a[i] - b[i] for i in range(len(a))]
530 ns ± 16.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit list(map(lambda x, y: x - y, a, b))
546 ns ± 16.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit np.subtract(a,b)
2.68 µs ± 80.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit list(np.array(a) - np.array(b))
2.82 µs ± 113 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.matrix(a) - np.matrix(b)
12.3 µs ± 437 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
使用map
は明らかに最速です。驚くべきことにnumpy
、最も遅いです。a
最初にリストを配列b
に変換するコストnumpy
が、ベクトル化による効率の向上を上回るボトルネックであることが判明しました。
%timeit a = np.array([2,2,2]); b=np.array([1,1,1])
1.55 µs ± 54.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
a = np.array([2,2,2])
b = np.array([1,1,1])
%timeit a - b
417 ns ± 12.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
この回答は、「通常の/理解しやすい」pythonic コードの書き方を示しています。
zip
誰もがそれについて知っているわけ
ではないので、使用しないことをお勧めします。
ソリューションでは、リスト内包表記と一般的な組み込み関数を使用します。
a = [2, 2, 2]
b = [1, 1, 1]
result = [a[i] - b[i] for i in range(len(a))]
Python の最も基本的な関数のみを使用するため、推奨されます
a = [2, 2, 2]
b = [1, 1, 1]
result = [x - b[i] for i, x in enumerate(a)]
a = [2, 2, 2]
b = [1, 1, 1]
result = list(map(lambda x, y: x - y, a, b))
これを試して:
list(array([1,2,3])-1)