Python 3D数组中最后两个非零元素的平均值
我有一个(n×I×j)-3D numpy数组:Python 3D数组中最后两个非零元素的平均值,python,numpy,multidimensional-array,mean,Python,Numpy,Multidimensional Array,Mean,我有一个(n×I×j)-3D numpy数组:a_3D_数组(2×5×3) 对于n中的每个列j,我想提取最后2个非零元素并计算平均值,然后将结果放入(n×j)数组中。我现在做的是使用for循环 import numpy as np a_3d_array = np.array([[[1, 2, 3], [1, 1, 1], [2, 2, 2], [0,
a_3D_数组
(2×5×3)
对于n中的每个列j,我想提取最后2个非零元素并计算平均值,然后将结果放入(n×j)数组中。我现在做的是使用for循环
import numpy as np
a_3d_array = np.array([[[1, 2, 3],
[1, 1, 1],
[2, 2, 2],
[0, 3, 3],
[0, 0, 4]],
[[1, 2, 3],
[2, 2, 2],
[3, 3, 3],
[0, 4, 4],
[0, 0, 5]]])
aveCol = np.zeros([2,3])
for n in range(2):
for j in range(3):
temp = a_3d_array[n,:,j]
nonzero_array = temp[np.nonzero(temp)]
aveCol[n, j] = np.mean(nonzero_array[-2:])
为了得到想要的结果
print(aveCol)
[[1.5 2.5 3.5] [2.5 3.5 4.5]]
那很好。但我想知道是否有更好的蟒蛇式方法来做同样的事情
我发现与我的问题最相似的是。但是我不太理解在稍微不同的上下文中解释的答案。您可以使用
filter
方法从数组中过滤出0
s
以下是一种列表理解方法:
import numpy as np
a_3d_array = np.array([[[1, 2, 3],
[1, 1, 1],
[2, 2, 2],
[0, 3, 3],
[0, 0, 4]],
[[1, 2, 3],
[2, 2, 2],
[3, 3, 3],
[0, 4, 4],
[0, 0, 5]]])
aveCol = np.array([[np.mean(list(filter(None, a_3d_array[n,:,j]))[-2:]) for j in range(3)] for n in range(2)])
print(aveCol)
输出:
[[1.5 2.5 3.5]
[2.5 3.5 4.5]]
@GBOFI注释:为了提高效率,请使用
aveCol = np.array([[sum([i for i in a_3d_array[n,:,j] if i][-2:])/2 for j in range(3)] for n in range(2)])
而不是
aveCol = np.array([[np.array([i for i in a_3d_array[n,:,j] if i][-2:]) for j in range(3)] for n in range(2)])
您可以使用
filter
方法从数组中筛选出0
s
以下是一种列表理解方法:
import numpy as np
a_3d_array = np.array([[[1, 2, 3],
[1, 1, 1],
[2, 2, 2],
[0, 3, 3],
[0, 0, 4]],
[[1, 2, 3],
[2, 2, 2],
[3, 3, 3],
[0, 4, 4],
[0, 0, 5]]])
aveCol = np.array([[np.mean(list(filter(None, a_3d_array[n,:,j]))[-2:]) for j in range(3)] for n in range(2)])
print(aveCol)
输出:
[[1.5 2.5 3.5]
[2.5 3.5 4.5]]
@GBOFI注释:为了提高效率,请使用
aveCol = np.array([[sum([i for i in a_3d_array[n,:,j] if i][-2:])/2 for j in range(3)] for n in range(2)])
而不是
aveCol = np.array([[np.array([i for i in a_3d_array[n,:,j] if i][-2:]) for j in range(3)] for n in range(2)])
TL;据我所知,DR是最快的
每个
m
都是一个n×i 2D数组,接下来我们取其转置的r
ow,即执行计算的“列”——在这个“列”上,我们丢弃所有零,最后两个非零元素求和并取平均值
In [17]: np.array([[sum(r[r!=0][-2:])/2 for r in m.T] for m in a])
Out[17]:
array([[1.5, 2.5, 3.5],
[2.5, 3.5, 4.5]])
编辑1 它看起来比你的循环快
In [19]: %%timeit
...: avg = np.zeros([2,3])
...: for n in range(2):
...: for j in range(3):
...: temp = a[n,:,j]
...: nz = temp[np.nonzero(temp)]
...: avg[n, j] = np.mean(nz[-2:])
95.1 µs ± 596 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [20]: %timeit np.array([[sum(r[r!=0][-2:])/2 for r in m.T] for m in a])
45.5 µs ± 394 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
编辑2
编辑3
Edit4突发新闻信息 安回答中的罪魁祸首是
np.mean
In [29]: %timeit np.array([[sum(list(filter(None, a[n,:,j]))[-2:])/2 for j in range(3)] for n in range(2)])
32.7 µs ± 111 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
TL;据我所知,DR是最快的
每个
m
都是一个n×i 2D数组,接下来我们取其转置的r
ow,即执行计算的“列”——在这个“列”上,我们丢弃所有零,最后两个非零元素求和并取平均值
In [17]: np.array([[sum(r[r!=0][-2:])/2 for r in m.T] for m in a])
Out[17]:
array([[1.5, 2.5, 3.5],
[2.5, 3.5, 4.5]])
编辑1 它看起来比你的循环快
In [19]: %%timeit
...: avg = np.zeros([2,3])
...: for n in range(2):
...: for j in range(3):
...: temp = a[n,:,j]
...: nz = temp[np.nonzero(temp)]
...: avg[n, j] = np.mean(nz[-2:])
95.1 µs ± 596 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [20]: %timeit np.array([[sum(r[r!=0][-2:])/2 for r in m.T] for m in a])
45.5 µs ± 394 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
编辑2
编辑3
Edit4突发新闻信息 安回答中的罪魁祸首是
np.mean
In [29]: %timeit np.array([[sum(list(filter(None, a[n,:,j]))[-2:])/2 for j in range(3)] for n in range(2)])
32.7 µs ± 111 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
您可以获取数组
a
的索引,用负数标记零项,排序、限制,然后将结果用作索引:
i=np.索引(a.形状)
i[:,a==0]=-1
i=np.sort(i,轴=2)
i=i[:,:,-2:,:]
a[元组(i)].平均值(轴=1)
#数组([[1.5,2.5,3.5],
# [2.5, 3.5, 4.5]])
您可以获取数组的索引a
,用负数标记零项,排序、限制,然后将结果用作索引:
i=np.索引(a.形状)
i[:,a==0]=-1
i=np.sort(i,轴=2)
i=i[:,:,-2:,:]
a[元组(i)].平均值(轴=1)
#数组([[1.5,2.5,3.5],
# [2.5, 3.5, 4.5]])
因为这是完全有效的代码;这可能是更好的位置(请删除这个问题,如果你决定张贴在那里)谢谢你杰弗克,我不知道有另一个合适的网站,要求一个工作代码。由于我已经收到了这篇文章的两个答案,这次我将离开我的文章。但是我会从下一次去另一个网站!好球!他们是真正的代码评审专家,在那里你会得到很多很好的建议;这可能是更好的位置(请删除这个问题,如果你决定张贴在那里)谢谢你杰弗克,我不知道有另一个合适的网站,要求一个工作代码。由于我已经收到了这篇文章的两个答案,这次我将离开我的文章。但是我会从下一次去另一个网站!好球!他们是真正的代码评审专家,你会在那里得到很多很好的建议。嗨,我最终发现你的解决方案实际上是最快的,只要你使用sum()/2
代替了np.mean
-我想当取2个数字的平均值时,Numpy函数的开销是不合适的…谢谢你的建议。我真的很感激。嗨,我最终发现你的解决方案实际上是最快的,只要你用sum()/2
代替np.mean
——我想当取两个数字的平均值时,Numpy函数的开销就不合适了……谢谢你的建议。我真的很感激。