2 डी सरणी में प्रति कॉलम दूसरा न्यूनतम मान प्राप्त करें


15

मैं प्रत्येक कॉलम से दूसरा न्यूनतम मूल्य कैसे प्राप्त कर सकता हूं? मेरे पास यह सरणी है:

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]

क्या आपने कुछ भी करने की कोशिश की है? ?
मेहा पारेख

प्रति कॉलम दूसरा न्यूनतम ?
निकोलस गेरविस

जवाबों:


12

यह कोशिश करो, सिर्फ एक लाइन में:

[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]

6

numpyसरणियों पर संचालन numpyकार्यों के साथ किया जाना चाहिए , इसलिए इस पर एक नज़र डालें:

np.sort(A, axis=0)[1, :]
Out[61]: array([54, 53, 59, 36, 40, 44])

यह सबसे अच्छा समाधान है जहाँ तक मुझे पता है, यह सब कुछ अंदर रखता है numpy, मुझे लगता है कि समाधान lambdaको धीमा करना चाहिए heapq.nsmallest। सबसे अच्छा लगता है कि सब कुछ तेजी से रखने के लिएnumpy
जमीलाक

3

आप 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समारोह छोटे 2 डी सूचियों के लिए सबसे तेजी से समाधान है का उपयोग करते समय zipके साथ heapq.nsmallestशो बड़ा 2 डी सूचियों पर सबसे अच्छा होना करने के लिए


1
बस एक जंगली विचार: क्या ये परिणाम इस तथ्य से प्रभावित हो सकते हैं कि आपने ऐसी संख्याएँ उत्पन्न की हैं जो सुन्न नहीं हैं? इसके अलावा, एक सरणी के बजाय एक सूची में रैंडम रिटर्न नहीं बनाया जाएगा?
निकोलस गेरविस

1

मुझे आशा है कि मैंने आपके प्रश्न को सही ढंग से समझा है, लेकिन या तो यहां मेरे समाधान का तरीका है, मुझे यकीन है कि ऐसा करने का एक अधिक प्रभावी तरीका है, लेकिन यह काम करता है

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)

यहाँ छवि विवरण दर्ज करें


0

यह मानते हुए कि 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 जिसके यह पूरी तरह से सॉर्ट करता है।


0
>>> 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]

पुराना: प्रत्येक पंक्ति में दूसरा न्यूनतम आइटम

>>> [sorted(set(items))[1] for items in A]
[1, 7, 13, 19, 25]

क्या कॉलम के बजाय प्रत्येक पंक्ति में दूसरा आइटम नहीं मिल रहा है?
पैक्सिडाब्लो

@paxdiablo हाँ सूचना के लिए धन्यवाद। अद्यतन उत्तर।
दिशिन एच गोयानी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.