函数应用在numpy的matrix行/列上
我正在使用Numpy将数据存储到matrix中。 从R背景来看,在matrix的行/列或两者上应用函数的方法非常简单。
有没有类似的python/ numpy组合? 编写我自己的小实现并不是一个问题,但是在我看来,大多数我提出的版本将比现有的实现效率/内存密集程度低得多。
我想避免从numpymatrix复制到局部variables等,这是可能的吗?
我试图实现的function主要是简单的比较(例如某个列的数量小于数量x,或者有多less个元素的绝对值大于y)。
几乎所有的numpy函数都在整个数组上运行,并且/或者可以被告知在特定的轴(行或列)上运行。
只要你可以根据作用在numpy数组或数组切片上的numpy函数来定义你的函数,你的函数将自动在整个数组,行或列上运行。
询问如何实现特定function以获得更具体的build议可能会更有帮助。
Numpy提供了np.vectorize和np.frompyfunc函数,可以将对数字进行操作的Python函数转换为在numpy数组上运行的函数。
例如,
def myfunc(a,b): if (a>b): return a else: return b vecfunc = np.vectorize(myfunc) result=vecfunc([[1,2,3],[5,6,9]],[7,4,5]) print(result) # [[7 4 5] # [7 6 9]]
(当第二个数组较大时,第一个数组的元素被第二个数组的相应元素replace)
但不要太激动; np.vectorize
和np.frompyfunc
只是语法糖 。 他们实际上并没有让你的代码更快。 如果你的底层Python函数一次只运行一个值,那么np.vectorize
会一次给它一个项目,整个操作将会非常慢(与使用调用某个底层C的numpy函数相比, Fortran实现)。
要计算列x
元素数小于数y
,可以使用如下expression式:
(array['x']<y).sum()
例如:
import numpy as np array=np.arange(6).view([('x',np.int),('y',np.int)]) print(array) # [(0, 1) (2, 3) (4, 5)] print(array['x']) # [0 2 4] print(array['x']<3) # [ True True False] print((array['x']<3).sum()) # 2
基于一个或多个条件从NumPy数组中select元素很简单,使用NumPy的精美密集的语法:
>>> import numpy as NP >>> # generate a matrix to demo the code >>> A = NP.random.randint(0, 10, 40).reshape(8, 5) >>> A array([[6, 7, 6, 4, 8], [7, 3, 7, 9, 9], [4, 2, 5, 9, 8], [3, 8, 2, 6, 3], [2, 1, 8, 0, 0], [8, 3, 9, 4, 8], [3, 3, 9, 8, 4], [5, 4, 8, 3, 0]])
第2列有多less元素大于6?
>>> ndx = A[:,1] > 6 >>> ndx array([False, True, False, False, True, True, True, True], dtype=bool) >>> NP.sum(ndx) 5
A的最后一列有多less元素的绝对值大于3?
>>> A = NP.random.randint(-4, 4, 40).reshape(8, 5) >>> A array([[-4, -1, 2, 0, 3], [-4, -1, -1, -1, 1], [-1, -2, 2, -2, 3], [ 1, -4, -1, 0, 0], [-4, 3, -3, 3, -1], [ 3, 0, -4, -1, -3], [ 3, -4, 0, -3, -2], [ 3, -4, -4, -4, 1]]) >>> ndx = NP.abs(A[:,-1]) > 3 >>> NP.sum(ndx) 0
A的前两行有多less个元素大于或等于2?
>>> ndx = A[:2,:] >= 2 >>> NP.sum(ndx.ravel()) # 'ravel' just flattens ndx, which is originally 2D (2x5) 2
NumPy的索引语法非常接近R的; 考虑到你在R中的stream畅度,这里是R和NumPy在这个上下文中的主要区别:
NumPy 指数是从零开始的 ,在R中,索引从1开始
NumPy(如Python)允许您使用负向索引从右到左进行索引 – 例如,
# to get the last column in A A[:, -1], # to get the penultimate column in A A[:, -2] # this is a big deal, because in R, the equivalent expresson is: A[, dim(A)[0]-2]
NumPy使用冒号“:”符号来表示“非重复” (例如在R中)以获得A中的前三行,您将使用A [1:3,]。 在NumPy中,你将使用A [0:2,:](在NumPy中,“0”不是必须的,实际上最好使用A [:2,:]
我也来自更多的R背景,碰上缺less更多function的应用,可能需要短暂的定制function。 我见过的论坛build议使用基本的numpy函数,因为其中许多处理数组。 然而,我一直在困惑“本地”numpy函数处理数组的方式(有时0是行方式和1列方式,有时相反)。
使用apply_along_axis来实现更灵活的函数的个人解决scheme是将它们与Python中可用的隐式lambda函数结合起来。 对于使用更多函数式编程风格的R思想者,Lambda函数应该很容易理解,就像在R函数apply,sapply,lapply等中一样。
所以,例如,我想在matrix中应用variables的标准化。 在R中有一个函数用于这个(scale),但是你也可以使用apply来轻松创build它:
(R码)
apply(Mat,2,function(x) (x-mean(x))/sd(x) )
你会看到如何应用函数体(x-mean(x))/ sd(x)是我们无法直接为python apply_along_axis键入的位。 使用lambda这很容易实现一套价值,所以:
(python)
import numpy as np vec=np.random.randint(1,10,10) # some random data vector of integers (lambda x: (x-np.mean(x))/np.std(x) )(vec)
然后,我们所需要的就是把这个插入到python apply中,并通过apply_along_axis传递感兴趣的数组
Mat=np.random.randint(1,10,3*4).reshape((3,4)) # some random data vector np.apply_along_axis(lambda x: (x-np.mean(x))/np.std(x),0,Mat )
显然,lambda函数可以作为一个单独的函数来实现,但是我想整个过程是使用包含在应用起源行中的相当小的函数。
希望对你有帮助 !
pandas对此非常有用。 例如, DataFrame.apply()和groupby的apply()应该可以帮到你。