Her bir sütundan ikinci minimum değeri nasıl alabilirim? Bu dizi var:
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]]
Çıktı gibi istiyorum:
A = [54 53 59 36 40 44]
Her bir sütundan ikinci minimum değeri nasıl alabilirim? Bu dizi var:
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]]
Çıktı gibi istiyorum:
A = [54 53 59 36 40 44]
Yanıtlar:
Bunu sadece bir satırda deneyin:
[sorted(i)[1] for i in zip(*A)]
eylemde:
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]
zip(*A)
listelerinizi sütunların satır haline gelmesi için değiştirir.
ve yinelenen değeriniz varsa, örneğin:
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
Her ikisini de atlamanız gerekiyorsa 35
, şunları kullanabilirsiniz set()
:
In [29]: [sorted(list(set(i)))[1] for i in zip(*A)]
Out[29]: [54, 53, 50, 36, 40, 44]
numpy
Diziler üzerindeki işlemler numpy
işlevlerle yapılmalıdır , bu yüzden şuna bakın:
np.sort(A, axis=0)[1, :]
Out[61]: array([54, 53, 59, 36, 40, 44])
numpy
, her şeyi içeri alıyor , bence çözümü lambda
yavaşlatmalı heapq.nsmallest
. Her şeyi hızlı tutmak için en iyi görünüyornumpy
heapq.nsmallest kullanabilirsiniz
from heapq import nsmallest
[nsmallest(2, e)[-1] for e in zip(*A)]
çıktı:
[54, 53, 50, 36, 40, 44]
Önceden yayınlanan farklı çözümlerin performansını karşılaştırmak için basit bir karşılaştırma ekledim:
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()
Kullanımı zip
ile sorted
kullanırken fonksiyonu küçük 2d listeler için en hızlı çözüm zip
ile heapq.nsmallest
büyük 2d listelerinde en iyi olmak için gösteriler
Umarım sorunuzu doğru bir şekilde anladım, ancak her iki şekilde de benim çözümüm, bunu yapmanın daha zarif bir yolu olduğundan eminim ama işe yarıyor
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,50,76,57,44]]
#rotate the array 90deg
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])
print(result)
Varsayılırsa A
olan numpy.array
(bu geçerlidir eğer eklemeyi düşünün lütfen numpy
sorunuzun etiketi) ardından kullanmak olabilir apply_along_axis
o aşağıdaki yolu:
import heap
import numpy as np
A = np.array([[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]])
second_mins = np.apply_along_axis(lambda x:heapq.nsmallest(2,x)[-1], 0, A)
print(second_mins) # [54 53 59 36 40 44]
Heapq.nsmallest kullandığım gibi sorted
, tam sıralamadan farklı olarak, en küçük 2 öğeyi almak için gerektiği kadar sıralama yaptığımı unutmayın .
>>> A = np.arange(30).reshape(5,6).tolist()
>>> A
[[0, 1, 2, 3, 4, 5],
[6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29]]
Güncellendi : Kullanarak set
listenin kopyalanmasını ve aktarılmasını önlemek için kullanınzip(*A)
>>> [sorted(set(items))[1] for items in zip(*A)]
[6, 7, 8, 9, 10, 11]
eski: her satırdaki ikinci minimum öğe
>>> [sorted(set(items))[1] for items in A]
[1, 7, 13, 19, 25]