ฉันจะรับค่าต่ำสุดที่สองจากแต่ละคอลัมน์ได้อย่างไร ฉันมีชุดนี้:
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]]
ฉันต้องการที่จะมีผลลัพธ์เช่น:
A = [54 53 59 36 40 44]
ฉันจะรับค่าต่ำสุดที่สองจากแต่ละคอลัมน์ได้อย่างไร ฉันมีชุดนี้:
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]]
ฉันต้องการที่จะมีผลลัพธ์เช่น:
A = [54 53 59 36 40 44]
คำตอบ:
ลองสิ่งนี้ในหนึ่งบรรทัด:
[sorted(i)[1] for i in zip(*A)]
ในการดำเนินการ:
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)
จะย้ายรายการรายการของคุณเพื่อให้คอลัมน์กลายเป็นแถว
และหากคุณมีค่าซ้ำกันตัวอย่างเช่น:
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
หากคุณต้องการข้ามทั้งสอง35
คุณสามารถใช้set()
:
In [29]: [sorted(list(set(i)))[1] for i in zip(*A)]
Out[29]: [54, 53, 50, 36, 40, 44]
การดำเนินการในnumpy
อาร์เรย์ควรทำกับnumpy
ฟังก์ชั่นดังนั้นให้ดูที่นี่:
np.sort(A, axis=0)[1, :]
Out[61]: array([54, 53, 59, 36, 40, 44])
numpy
นั้นฉันคิดว่าวิธีแก้ปัญหาlambda
ต้องชะลอตัวลง heapq.nsmallest
ดูเหมือนว่าดีที่สุดเพื่อให้ทุกอย่างรวดเร็วในnumpy
คุณสามารถใช้heapq.nsmallest
from heapq import nsmallest
[nsmallest(2, e)[-1] for e in zip(*A)]
เอาท์พุท:
[54, 53, 50, 36, 40, 44]
ฉันเพิ่มมาตรฐานง่ายๆเพื่อเปรียบเทียบประสิทธิภาพของโซลูชันที่โพสต์แล้ว
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()
ใช้zip
กับsorted
ฟังก์ชั่นเป็นวิธีที่เร็วที่สุดสำหรับรายการ 2d ขนาดเล็กในขณะที่ใช้zip
กับheapq.nsmallest
การแสดงให้ดีที่สุดในรายการ 2d ใหญ่
ฉันหวังว่าฉันเข้าใจคำถามของคุณอย่างถูกต้อง แต่ไม่ว่าจะเป็นวิธีการแก้ปัญหาของฉันฉันแน่ใจว่ามีวิธีที่สง่างามกว่าในการทำเช่นนี้ แต่ก็ใช้งานได้
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)
สมมติว่าA
เป็นnumpy.array
(หากนี่ถือเป็นจริงโปรดลองเพิ่มnumpy
แท็กในคำถามของคุณ) จากนั้นคุณอาจใช้apply_along_axis
วิธีต่อไปนี้:
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เท่าที่จะทำการคัดแยกได้มากเท่าที่ต้องการเพื่อให้ได้องค์ประกอบที่เล็กที่สุด 2 ตัวsorted
ซึ่งแตกต่างจากการเรียงลำดับที่สมบูรณ์
>>> 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]]
อัปเดต : ใช้set
เพื่อป้องกันการทำซ้ำและโอนย้ายรายการโดยใช้zip(*A)
>>> [sorted(set(items))[1] for items in zip(*A)]
[6, 7, 8, 9, 10, 11]
old: รายการขั้นต่ำที่สองในแต่ละแถว
>>> [sorted(set(items))[1] for items in A]
[1, 7, 13, 19, 25]