如何在Python中的矩阵中为每个元素应用函数?

时间:2015-10-31 12:17:04

标签: python python-3.x numpy

我有一个三角形矩阵,每行有3个顶点: ELEMENTSET:

Element Number      Vertices 
    2           473    1159   917
    3           271    1026   816

我还有一个节点矩阵,为每个顶点分配一个2d协调 节点集:

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 dimmensions数组,当我假设得到一个数组与原始向量相同的dimmension

a.calcArea(f[0,:],f[1,:],f[2,:])
 array([ 7.5,  0. ])

2 个答案:

答案 0 :(得分:2)

如果您可以将数据重新排列为一组三个2D数组,其中包含所有三角形的第一个,第二个和第三个顶点的 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

答案 1 :(得分:1)

使用您的var po = $('#select-filter-item').val(); 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)扩展实际上是对第一维的一种交互。

*有3个参数,但calcArea沿着self.calcArea(*self.elementSet[:,-3:])的第一维扩展,而不是最后一个尺寸3维。尝试

elementSet