[英]How to apply a function for each element in a matrix in Python?
我有一個三角形矩陣,其中每條線具有3個頂點:elementSet:
Element Number Vertices
2 473 1159 917
3 271 1026 816
而且我還有一個節點矩陣,為每個頂點的nodeSet分配一個二維坐標:
Vertice Number (X,Y)
917 5.487167292060809 2.195789288329368
271 5.448888739433895 2.38822856765269
我已經編寫了一些方法來處理面積計算,它們包含在一個類中:
def findArea(self):
self.elementsArea = nu.zeros((self.elementSet.shape[0],1))
self.elementsArea[:] = self.calcArea(*self.elementSet[:,-3:])
#Calculate the area of 3 points
def calcArea (self,p1,p2,p3):
[p1,p2,p3] = [self.nodeCoord(p1),self.nodeCoord(p2),self.nodeCoord(p3)]
return 0.5*abs(p1[Xc]*(p2[Yc] - p3[Yc]) + p2[Xc]*(p3[Yc]-p1[Yc]) + p3[Xc]*(p1[Yc] - p2[Yc]))
# returns the vertices of a point
def nodeCoord(self, point):
return(self.nodeSet[point-1,-3:-1])
函數calcArea
可以正常工作,但我想將函數應用於矩陣的每個元素並分配給另一個矩陣,而無需使用循環。
我必須寫一些像:
A[:] = func(B[:])
在def findArea()
我嘗試執行類似的操作,但它給了我以下錯誤:
calcArea() takes 4 positional arguments but 2171 were given
我想使用calcArea()來計算通過數組的面積作為參數,就像我在此示例中所做的一樣:
import numpy as np
def test(x,y):
return x*y
f = np.array([[1,2,5,6,7] , [3,4,9,6,7] ,[6,7,23,34,32]])
print(test(f[0,:],f[1,:]))
我正在嘗試應用calcArea方法,但是當我假設要獲得與原始向量相同的維度時,我現在只得到2個維度數組
a.calcArea(f[0,:],f[1,:],f[2,:])
array([ 7.5, 0. ])
如果您可以將數據重新排列為三個二維數組的集合,其中包含所有三角形的第一個,第二個和第三個頂點的x,y坐標(例如,尺寸為(2, n)
,其中n
是三角形的數量),那么您可以輕松地將所有三角形的計算向量化:
import numpy as np
# adapted from your code. here p1, p2 and p3 are (2, ...) vectors of x,y coords.
def triangle_area(p1, p2, p3):
return 0.5 * np.abs(p1[0] * (p2[1] - p3[1]) +
p2[0] * (p3[1] - p1[1]) +
p3[0] * (p1[1] - p2[1]))
n = 100000
# some random vertex data
vert_data = np.random.randn(3, 2, n)
# each of these is a (2, n) vector of x,y coordinates
P1, P2, P3 = vert_data
# a 100000-long vector of areas
areas = triangle_area(P1, P2, P3)
定時:
In [41]: %%timeit P1, P2, P3 = np.random.randn(3, 2, 100000)
....: triangle_area(P1, P2, P3)
....:
1000 loops, best of 3: 1.09 ms per loop
使用您的test
和f
:
In [420]: test(f[0,:],f[1,:])
Out[420]: array([ 3, 8, 45, 36, 49])
In [421]: test(*f[:2,:])
Out[421]: array([ 3, 8, 45, 36, 49])
在第一維上建立索引時,(* ...)執行相同的操作。 但是在您的課堂情況下,您嘗試選擇列而不是行
In [422]: f1=f.T
In [423]: test(f1[:,1],f1[:,2])
Out[423]: array([ 18, 28, 207, 204, 224])
In [424]: test(*f1[:,:2])
...
TypeError: test() takes 2 positional arguments but 5 were given
(*f1...)
擴展為(f1[0,:2],f1[1,:2],f1[2,:2],etc)
。 *
擴展實際上是對第一維的交互。
calcArea
接受3個參數,但self.calcArea(*self.elementSet[:,-3:])
沿elementSet
的第一個維度擴展,而不是最后一個3維度。 嘗試
self.calcArea(self.elementSet[:,0], self.elementSet[:,1], self.elementSet[:,2])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.