Mr *_*Dan 15 python arrays numpy list python-3.x
如何从每列中获得第二个最小值?我有这个数组:
A = [[72 76 44 62 81 31]
[54 36 82 71 40 45]
[63 59 84 36 34 51]
[58 53 59 22 77 64]
[35 77 60 76 57 44]]
Run Code Online (Sandbox Code Playgroud)
我希望有如下输出:
A = [54 53 59 36 40 44]
Run Code Online (Sandbox Code Playgroud)
Meh*_*far 12
试试这个,只用一行:
[sorted(i)[1] for i in zip(*A)]
Run Code Online (Sandbox Code Playgroud)
在行动:
In [12]: A = [[72, 76, 44, 62, 81, 31],
...: [54 ,36 ,82 ,71 ,40, 45],
...: [63 ,59, 84, 36, 34 ,51],
...: [58, 53, 59, 22, 77 ,64],
...: [35 ,77, 60, 76, 57, 44]]
In [18]: [sorted(i)[1] for i in zip(*A)]
Out[18]: [54, 53, 59, 36, 40, 44]
Run Code Online (Sandbox Code Playgroud)
zip(*A)将转置您的列表列表,使列变为行。
如果您有重复的值,例如:
In [19]: A = [[72, 76, 44, 62, 81, 31],
...: [54 ,36 ,82 ,71 ,40, 45],
...: [63 ,59, 84, 36, 34 ,51],
...: [35, 53, 59, 22, 77 ,64], # 35
...: [35 ,77, 50, 76, 57, 44],] # 35
Run Code Online (Sandbox Code Playgroud)
如果您需要跳过两个35s,您可以使用set():
In [29]: [sorted(list(set(i)))[1] for i in zip(*A)]
Out[29]: [54, 53, 50, 36, 40, 44]
Run Code Online (Sandbox Code Playgroud)
对numpy数组的操作应该用numpy函数来完成,所以看看这个:
np.sort(A, axis=0)[1, :]
Run Code Online (Sandbox Code Playgroud)
Out[61]: array([54, 53, 59, 36, 40, 44])
Run Code Online (Sandbox Code Playgroud)
你可以使用heapq.nsmallest
from heapq import nsmallest
[nsmallest(2, e)[-1] for e in zip(*A)]
Run Code Online (Sandbox Code Playgroud)
输出:
[54, 53, 50, 36, 40, 44]
Run Code Online (Sandbox Code Playgroud)
我添加了一个简单的基准测试来比较已经发布的不同解决方案的性能:
from simple_benchmark import BenchmarkBuilder
from heapq import nsmallest
b = BenchmarkBuilder()
@b.add_function()
def MehrdadPedramfar(A):
return [sorted(i)[1] for i in zip(*A)]
@b.add_function()
def NicolasGervais(A):
return np.sort(A, axis=0)[1, :]
@b.add_function()
def imcrazeegamerr(A):
rotated = zip(*A[::-1])
result = []
for arr in rotated:
# sort each 1d array from min to max
arr = sorted(list(arr))
# add the second minimum value to result array
result.append(arr[1])
return result
@b.add_function()
def Daweo(A):
return np.apply_along_axis(lambda x:heapq.nsmallest(2,x)[-1], 0, A)
@b.add_function()
def kederrac(A):
return [nsmallest(2, e)[-1] for e in zip(*A)]
@b.add_arguments('Number of row/cols (A is square matrix)')
def argument_provider():
for exp in range(2, 18):
size = 2**exp
yield size, [[randint(0, 1000) for _ in range(size)] for _ in range(size)]
r = b.run()
r.plot()
Run Code Online (Sandbox Code Playgroud)
使用zipwithsorted函数是小型 2d 列表的最快解决方案,而使用zipwithheapq.nsmallest显示是大型 2d 列表的最佳解决方案