numpy.einsum()
यदि आप इसे सहजता से समझें, तो इस विचार को समझना बहुत आसान है। एक उदाहरण के रूप में, आइए मैट्रिक्स गुणन से जुड़े एक सरल विवरण के साथ शुरू करें ।
उपयोग करने के लिए numpy.einsum()
, आपको बस इतना करना होगा कि तथाकथित सब्सक्राइबर्स स्ट्रिंग को एक तर्क के रूप में पारित किया जाए , उसके बाद आपके इनपुट एरेज़ के बाद ।
मान लें कि आपके पास दो 2D सरणियाँ हैं, A
और B
, और आप मैट्रिक्स गुणा करना चाहते हैं। तो तुम करते हो:
np.einsum("ij, jk -> ik", A, B)
यहाँ सबस्क्रिप्ट स्ट्रिंग ij
सरणी से मेल खाती है, A
जबकि सबस्क्रिप्ट स्ट्रिंग jk
सरणी से मेल खाती है B
। इसके अलावा, यहां ध्यान देने वाली सबसे महत्वपूर्ण बात यह है कि प्रत्येक सबस्क्रिप्ट स्ट्रिंग में वर्णों की संख्या को सरणी के आयामों से मेल खाना चाहिए । (यानी 2 डी सरणियों के लिए दो चार्ट, 3 डी सरणियों के लिए तीन चार्ट, और इसी तरह।) और यदि आप सबस्क्रिप्ट स्ट्रिंग्स ( हमारे मामले में) के बीच के वर्णों को दोहराते हैं , तो इसका मतलब है कि आप उन आयामों के साथ होने का योग चाहते हैं । इस प्रकार, वे योग-कम हो जाएंगे। (अर्थात वह आयाम चला जाएगा j
ein
)
इसके बाद सबस्क्रिप्ट स्ट्रिंग->
, हमारी परिणामी सरणी होगी। यदि आप इसे खाली छोड़ देते हैं, तो सब कुछ अभिव्यक्त हो जाएगा और परिणाम के रूप में एक स्केलर मूल्य वापस आ जाएगा। परिणामी सरणी में सबस्क्रिप्ट स्ट्रिंग के अनुसार आयाम होंगे । हमारे उदाहरण में, यह होगा ik
। यह सहज है क्योंकि हम जानते हैं कि मैट्रिक्स गुणा के लिए सरणी में स्तंभों A
की संख्या को सरणी में पंक्तियों की संख्या से मेल खाना है B
जो कि यहां हो रहा है (यानी हम सबस्क्रिप्ट स्ट्रिंगj
में चार को दोहराकर इस ज्ञान को सांकेतिक शब्दों में बदलते हैं )
यहाँ कुछ और np.einsum()
सामान्य टेनर या एनडी-सरणी संचालन को लागू करने के उपयोग / शक्ति को दर्शाते हुए कुछ और उदाहरण हैं , संक्षेप में।
इनपुट
# a vector
In [197]: vec
Out[197]: array([0, 1, 2, 3])
# an array
In [198]: A
Out[198]:
array([[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]])
# another array
In [199]: B
Out[199]:
array([[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]])
1) मैट्रिक्स गुणा (के समान np.matmul(arr1, arr2)
)
In [200]: np.einsum("ij, jk -> ik", A, B)
Out[200]:
array([[130, 130, 130, 130],
[230, 230, 230, 230],
[330, 330, 330, 330],
[430, 430, 430, 430]])
2) मुख्य-विकर्ण के साथ तत्व निकालें (समान np.diag(arr)
)
In [202]: np.einsum("ii -> i", A)
Out[202]: array([11, 22, 33, 44])
3) हेडमार्ड उत्पाद (अर्थात दो सरणियों का तत्व-वार उत्पाद) (समान arr1 * arr2
)
In [203]: np.einsum("ij, ij -> ij", A, B)
Out[203]:
array([[ 11, 12, 13, 14],
[ 42, 44, 46, 48],
[ 93, 96, 99, 102],
[164, 168, 172, 176]])
4) तत्व के लिहाज से squaring (के समान np.square(arr)
या arr ** 2
)
In [210]: np.einsum("ij, ij -> ij", B, B)
Out[210]:
array([[ 1, 1, 1, 1],
[ 4, 4, 4, 4],
[ 9, 9, 9, 9],
[16, 16, 16, 16]])
5) ट्रेस (यानी मुख्य-विकर्ण तत्वों का योग) (समान np.trace(arr)
)
In [217]: np.einsum("ii -> ", A)
Out[217]: 110
6) मैट्रिक्स ट्रांज़ोज़ (समान np.transpose(arr)
)
In [221]: np.einsum("ij -> ji", A)
Out[221]:
array([[11, 21, 31, 41],
[12, 22, 32, 42],
[13, 23, 33, 43],
[14, 24, 34, 44]])
7) बाहरी उत्पाद (वैक्टर के) (समान np.outer(vec1, vec2)
)
In [255]: np.einsum("i, j -> ij", vec, vec)
Out[255]:
array([[0, 0, 0, 0],
[0, 1, 2, 3],
[0, 2, 4, 6],
[0, 3, 6, 9]])
8) इनर प्रोडक्ट (वैक्टर के) (समान np.inner(vec1, vec2)
)
In [256]: np.einsum("i, i -> ", vec, vec)
Out[256]: 14
9) अक्ष 0 के साथ सम (समान np.sum(arr, axis=0)
)
In [260]: np.einsum("ij -> j", B)
Out[260]: array([10, 10, 10, 10])
10) अक्ष 1 के साथ सम (समान np.sum(arr, axis=1)
)
In [261]: np.einsum("ij -> i", B)
Out[261]: array([ 4, 8, 12, 16])
11) बैच मैट्रिक्स गुणन
In [287]: BM = np.stack((A, B), axis=0)
In [288]: BM
Out[288]:
array([[[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]],
[[ 1, 1, 1, 1],
[ 2, 2, 2, 2],
[ 3, 3, 3, 3],
[ 4, 4, 4, 4]]])
In [289]: BM.shape
Out[289]: (2, 4, 4)
# batch matrix multiply using einsum
In [292]: BMM = np.einsum("bij, bjk -> bik", BM, BM)
In [293]: BMM
Out[293]:
array([[[1350, 1400, 1450, 1500],
[2390, 2480, 2570, 2660],
[3430, 3560, 3690, 3820],
[4470, 4640, 4810, 4980]],
[[ 10, 10, 10, 10],
[ 20, 20, 20, 20],
[ 30, 30, 30, 30],
[ 40, 40, 40, 40]]])
In [294]: BMM.shape
Out[294]: (2, 4, 4)
12) अक्ष 2 के साथ सम (समान np.sum(arr, axis=2)
)
In [330]: np.einsum("ijk -> ij", BM)
Out[330]:
array([[ 50, 90, 130, 170],
[ 4, 8, 12, 16]])
13) सरणी में सभी तत्व (समान np.sum(arr)
)
In [335]: np.einsum("ijk -> ", BM)
Out[335]: 480
14) कई कुल्हाड़ियों (यानी हाशिए पर) पर सम
(समान np.sum(arr, axis=(axis0, axis1, axis2, axis3, axis4, axis6, axis7))
)
# 8D array
In [354]: R = np.random.standard_normal((3,5,4,6,8,2,7,9))
# marginalize out axis 5 (i.e. "n" here)
In [363]: esum = np.einsum("ijklmnop -> n", R)
# marginalize out axis 5 (i.e. sum over rest of the axes)
In [364]: nsum = np.sum(R, axis=(0,1,2,3,4,6,7))
In [365]: np.allclose(esum, nsum)
Out[365]: True
15) डबल डॉट प्रोडक्ट्स ( np.sum (हैसमर्ड-प्रोडक्ट) cf. 3 के समान )
In [772]: A
Out[772]:
array([[1, 2, 3],
[4, 2, 2],
[2, 3, 4]])
In [773]: B
Out[773]:
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
In [774]: np.einsum("ij, ij -> ", A, B)
Out[774]: 124
16) 2 डी और 3 डी सरणी गुणन
समीकरणों के रैखिक सिस्टम ( Ax = b ) को हल करने के दौरान ऐसा गुणन बहुत उपयोगी हो सकता है जहां आप परिणाम को सत्यापित करना चाहते हैं।
# inputs
In [115]: A = np.random.rand(3,3)
In [116]: b = np.random.rand(3, 4, 5)
# solve for x
In [117]: x = np.linalg.solve(A, b.reshape(b.shape[0], -1)).reshape(b.shape)
# 2D and 3D array multiplication :)
In [118]: Ax = np.einsum('ij, jkl', A, x)
# indeed the same!
In [119]: np.allclose(Ax, b)
Out[119]: True
इसके विपरीत, यदि किसी को np.matmul()
इस सत्यापन के लिए उपयोग करना है, तो हमें reshape
उसी तरह के परिणाम प्राप्त करने के लिए कुछ संचालन करना होगा:
# reshape 3D array `x` to 2D, perform matmul
# then reshape the resultant array to 3D
In [123]: Ax_matmul = np.matmul(A, x.reshape(x.shape[0], -1)).reshape(x.shape)
# indeed correct!
In [124]: np.allclose(Ax, Ax_matmul)
Out[124]: True
बोनस : यहां अधिक गणित पढ़ें: आइंस्टीन-संक्षेप और निश्चित रूप से यहां: Tensor-Notation
(A * B)^T
या समकक्ष होगाB^T * A^T
।