函数应用程序在numpy的矩阵行/列上

pet*_*etr 36 python numpy map-function

我正在使用Numpy将数据存储到矩阵中.来自R background,有一种非常简单的方法可以在行/列或矩阵两者上应用函数.

python/numpy组合有类似的东西吗?编写我自己的小实现并不是一个问题,但在我看来,我提出的大多数版本将比任何现有的实现效率低得多/内存密集.

我想避免从numpy矩阵复制到局部变量等,这可能吗?

我试图实现的函数主要是简单的比较(例如,某列的多少元素小于数字x或者有多少元素的绝对值大于y).

unu*_*tbu 43

几乎所有numpy函数都在整个数组上运行,和/或可以被告知在特定轴(行或列)上运行.

只要你可以定义作用于numpy的阵列或阵列切片numpy的功能方面的功能,你的功能将自动对整个阵列,行或列运行.

询问如何实现特定函数以获得更具体的建议可能更有帮助.


Numpy提供了np.vectorizenp.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]]
Run Code Online (Sandbox Code Playgroud)

(当第二个数组较大时,第一个数组的元素将被第二个数组的相应元素替换.)

但是不要太兴奋; np.vectorize并且np.frompyfunc只是语法糖.它们实际上并没有让你的代码更快.如果你的底层Python函数一次只运行一个值,那么np.vectorize它将一次为它提供一个项目,并且整个操作将非常慢(与使用调用一些底层C或Fortran实现的numpy函数相比) .


要计算列的x数量小于数字的数量y,可以使用如下表达式:

(array['x']<y).sum()
Run Code Online (Sandbox Code Playgroud)

例如:

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
Run Code Online (Sandbox Code Playgroud)


dou*_*oug 14

使用NumPy非常密集的语法,可以直接从基于一个或多个条件的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]])
Run Code Online (Sandbox Code Playgroud)


第2列中有多少元素大于6?

>>> ndx = A[:,1] > 6
>>> ndx
      array([False,  True, False, False,  True,  True,  True,  True], dtype=bool)
>>> NP.sum(ndx)
      5
Run Code Online (Sandbox Code Playgroud)


A的最后一列中有多少元素的绝对值大于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
Run Code Online (Sandbox Code Playgroud)


A的前两行中有多少元素大于或等于2?

>>> ndx = A[:2,:] >= 2
>>> NP.sum(ndx.ravel())    # 'ravel' just flattens ndx, which is originally 2D (2x5)
      2
Run Code Online (Sandbox Code Playgroud)

NumPy的索引语法非常接近于R; 鉴于你对R的流利程度,以下是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]
Run Code Online (Sandbox Code Playgroud)

NumPy使用冒号":"符号来表示"未剪切",例如在R中,以获得A中的前三行,您将使用A [1:3,].在NumPy中,你会使用A [0:2,:](在NumPy中,"0"不是必需的,实际上最好使用A [:2,:]


小智 7

我也来自更多的R背景,并且缺乏更多功能的应用,这可能需要简短的定制功能.我已经看到论坛建议使用基本的numpy函数,因为它们中的许多都处理数组.但是,我一直对"本机"numpy函数处理数组的方式感到困惑(有时0是行方式,1列是列,有时相反).

使用apply_along_axis,我对更灵活的函数的个人解决方案是将它们与python中可用的隐式lambda函数相结合.对于使用更多功能编程风格的R minded来说,Lambda函数应该很容易理解,比如R函数apply,sapply,lapply等.

因此,例如,我想在矩阵中应用变量的标准化.R中有一个函数(比例),但您也可以使用apply轻松构建它:

(R代码)

apply(Mat,2,function(x) (x-mean(x))/sd(x) ) 
Run Code Online (Sandbox Code Playgroud)

你看到里面函数的主体如何应用(x-mean(x))/ sd(x)是我们不能直接为python apply_along_axis键入的位.使用lambda,这很容易实现FOR ONE SET OF VALUES,因此:

(蟒蛇)

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)
Run Code Online (Sandbox Code Playgroud)

然后,我们需要的是将它插入python应用程序中并通过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 )
Run Code Online (Sandbox Code Playgroud)

显然,lambda函数可以作为一个单独的函数实现,但我想整个观点是使用包含在应用源的行中的相当小的函数.

希望对你有帮助 !