如何使用numpy apply_along_axis

如何解决如何使用numpy apply_along_axis

我有一个可以完全矢量化的问题,但是我没有足够的空间,所以我正在尝试使用numpy的apply_along_axis()实现一半的解决方案。

(注意:这是一个说明问题的玩具示例。换句话说,我不是在寻找执行此处功能的numpy或scipy函数-它不是真正的函数,一个简单的例子。)

我想做的是找出一种方法来访问每次迭代传递的轴的索引。

假设我们采用4 x 4矩阵:

    M = np.array(([0,1,1],[1,0],[0,1]))
    M 
   
   array([[0,1]])

并且想要计算每列相对于其他每一列的成对按位逻辑和,但是为了节省(大量)时间,我们仅计算i> j的列,其中j> i的索引(这样我们最终带有三角形矩阵)。

在熊猫中,我可以使用apply()很容易地做到这一点,但是对于我的目的来说太慢了。

我知道scikit-learn中有成对函数,但是请假定这些函数不符合我的目的(我的函数比这个玩具更复杂)

如果我要使用numpy的apply_long_axis(),则只能算出如何比较所有i,j和j,i,而不是前面所述的较小问题。

这是我的解决方案:

def intersections_np(col,M):
    col = col[:,np.newaxis]
    intersection = (M & col).sum(0)
    return(intersection)

result_np = np.apply_along_axis(intersections_np,arr = M,axis = 0,M = M)
result_np

array([[2,3,2],2,3]],dtype=int32)

但是我真正想做的是:

def intersections_np(col,np.newaxis]
    start_index = <index_of_current_column> + 1
    other_cols = M[:,start_index:]
    intersection = (other_cols & col).sum(0)
    <possible padding of the array with nans here>
    return(intersection)

result_np = np.apply_along_axis(intersections_np,M = M)

并返回:

result_np

array([[nan,nan,nan],nan]],dtype=int32)

有人知道这样的事情可以做吗?

谢谢

解决方法

让我们做些时间。

您的基本apply

In [142]: timeit np.apply_along_axis(intersections_np,arr = M,axis = 0,M = M)                    
158 µs ± 3.97 µs per loop (mean ± std. dev. of 7 runs,10000 loops each)

等效迭代(从技术上讲,可能需要转置,结果是对称的,所以没关系):

In [143]: timeit np.array([intersections_np(M[:,i],M) for i in range(M.shape[1])])                   
65.4 µs ± 1.93 µs per loop (mean ± std. dev. of 7 runs,10000 loops each)

和@jfahne建议:

In [144]: %%timeit  
     ...: np.reshape(np.array([(M.T[i] & M.T[j]).sum(0) if j>i else 0 \ 
     ...: for i in range(len(M.T)) for j in range(len(M.T))]),(M.T).shape).T 
     ...:  
     ...:                                                                                            
95.2 µs ± 2.99 µs per loop (mean ± std. dev. of 7 runs,10000 loops each)

请注意,apply比普通迭代要慢。这与我过去的测试是一致的。 apply仅在数组为3d或更大时才有帮助,并且迭代是“丑陋”的双嵌套数组。那里比较漂亮,虽然还不算快。这是一种便利工具,而不是速度工具。

完全“矢量化”的解决方案(具有numpy广播等)

In [148]: (M[:,:,None] & M[:,None,:]).sum(0)                                                         
Out[148]: 
array([[2,1,1],[1,3,2],2,3]])
In [149]: timeit (M[:,:]).sum(0)                                                  
14.9 µs ± 182 ns per loop (mean ± std. dev. of 7 runs,100000 loops each)

它确实制作了一个中间(4,4,4)数组,并且没有避免重复,但是因为在Python级别上没有迭代,所以它非常快。试图将计算限制在较低(或较高)三角形上通常是不值得的。

但是,如果您确实想要较低的三角形和速度,请考虑使用numba。对于迭代问题,它可能很快(但要付出一定的灵活性)。


这是您的相交版本仅限于下三角形

In [159]: def foo(M): 
     ...:     m = M.shape[0] 
     ...:     res = np.full((m,m),np.nan) 
     ...:     for i in range(m-1): 
     ...:         temp = (M[:,i,(i+1):]).sum(0) 
     ...:         res[-temp.shape[0]:,i] = temp 
     ...:     return res 
     ...:      
     ...:                                                                                            
In [160]: foo(M)                                                                                     
Out[160]: 
array([[nan,nan,nan],[ 1.,0.,1.,2.,nan]])
In [161]: timeit foo(M)                                                                              
59.3 µs ± 2.42 µs per loop (mean ± std. dev. of 7 runs,10000 loops each)

与我的[143]基本相同的计时-&步骤中的计算较少,但是索引较多,因此速度变化很小。

,

这有一个相当不错的pythonic解决方案:

np.reshape(np.array([(M.T[i] & M.T[j]).sum(0) if j>i else 0 \
for i in range(len(M.T)) for j in range(len(M.T))]),(M.T).shape).T

使用M.T来访问列。生成的矢量将重塑为与转置数组相同的形状。然后将阵列转置回原始阵列形状,并产生所需的输出。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-