python - कई स्तंभों की तुलना करके अधिकतम मान प्राप्त करें और विशिष्ट मान लौटाएं




python-3.x pandas (6)

बिना numpy उपयोग के बिना:

  • सबसे पहले, इस समस्या के कुछ महान समाधान हैं, दूसरों द्वारा।
  • डेटा उस प्रश्न में प्रदान किया जाएगा, df रूप में
# find the max value in the Duration columns
max_value = max(df.filter(like='Dur', axis=1).max().tolist())

# get a Boolean match of the dataframe for max_value
df_max = df[df == mv]

# get the row index
max_index = df_max.dropna(how='all').index[0]

# get the column name
max_col = df_max.dropna(axis=1, how='all').columns[0]

# get column index
max_col_index = df.columns.get_loc(max_col)

# final
df.iloc[max_index, [0, max_col_index, max_col_index + 1]]

आउटपुट:

Sequence     1008
Duration3     981
Value3         82
Name: 7, dtype: int64

अपडेट करें

  • कल रात, वास्तव में 4 बजे, मैंने एक बेहतर समाधान को खारिज कर दिया, क्योंकि मैं अत्यधिक थक गया था।
    • मैंने Duration कॉलम के भीतर अधिकतम मान वापस करने के लिए max_value = max(df.filter(like='Dur', axis=1).max().tolist())
    • स्तंभ नाम वापस करने के लिए max_col_name = df.filter(like='Dur', axis=1).max().idxmax() , जहां अधिकतम मान होता है।
    • मैंने ऐसा इसलिए किया क्योंकि मेरे जोड़ मस्तिष्क ने मुझे बताया था कि मैं कॉलम में अधिकतम मूल्य के बजाय, कॉलम नामों का अधिकतम मूल्य वापस कर रहा हूं। उदाहरण के लिए:
test = ['Duration5', 'Duration2', 'Duration3']
print(max(test))
>>> 'Duration5'
  • यह क्यों overtired है, एक खराब समस्या को हल करने की स्थिति है
  • नींद और कॉफी के साथ, एक अधिक कुशल समाधान
    • दूसरों के समान, idmax के उपयोग में

नया और बेहतर समाधान:

# column name with max duration value
max_col_name = df.filter(like='Dur', axis=1).max().idxmax()

# index of max_col_name
max_col_idx =df.columns.get_loc(max_col_name)

# row index of max value in max_col_name
max_row_idx = df[max_col_name].idxmax()

# output with .loc
df.iloc[max_row_idx, [0, max_col_idx, max_col_idx + 1 ]]

आउटपुट:

Sequence     1008
Duration3     981
Value3         82
Name: 7, dtype: int64

उपयोग की जाने वाली विधियाँ:

मेरे पास एक डेटाफ्रेम है:

Sequence    Duration1   Value1  Duration2   Value2  Duration3   Value3
1001        145         10      125         53      458         33
1002        475         20      175         54      652         45
1003        685         57      687         87      254         88
1004        125         54      175         96      786         96
1005        475         21      467         32      526         32
1006        325         68      301         54      529         41
1007        125         97      325         85      872         78
1008        129         15      429         41      981         82
1009        547         47      577         52      543         83
1010        666         65      722         63      257         87

मैं (Duration1, Duration2, Duration3) में अवधि का अधिकतम मान ढूंढना चाहता हूं और संबंधित मान और क्रम लौटाता हूं।

मेरा वांछित आउटपुट:

Sequence,Duration3,Value3
1008,    981,      82

आप किसी स्तंभ के अधिकतम मूल्य का सूचकांक प्राप्त कर सकते हैं:

>>> idx = df['Duration3'].idxmax()
>>> idx
7

और प्रासंगिक कॉलम केवल उपयोग करने पर:

>>> df_cols = df[['Sequence', 'Duration3', 'Value3']]
>>> df_cols.loc[idx]
Sequence     1008
Duration3     981
Value3         82
Name: 7, dtype: int64

तो, बस एक अच्छा कार्य में सभी लपेटो:

def get_max(df, i):
    idx = df[f'Duration{i}'].idxmax()
    df_cols = df[['Sequence', f'Duration{i}', f'Value{i}']]
    return df_cols.loc[idx]

और 1..3 से अधिक लूप:

>>> max_rows = [get_max(i) for i in range(1, 4)]
>>> print('\n\n'.join(map(str, max_rows)))
Sequence     1003
Duration1     685
Value1         57
Name: 2, dtype: int64

Sequence     1010
Duration2     722
Value2         63
Name: 9, dtype: int64

Sequence     1008
Duration3     981
Value3         82
Name: 7, dtype: int64

यदि आप इन 3 को एक अधिकतम पंक्ति में कम करना चाहते हैं, तो आप निम्न कार्य कर सकते हैं:

>>> pairs = enumerate(max_rows, 1)
>>> by_duration = lambda x: x[1][f'Duration{x[0]}']
>>> i, max_row = max(pairs, key=by_duration)
>>> max_row
Sequence     1008
Duration3     981
Value3         82
Name: 7, dtype: int64

यदि मैं प्रश्न को सही ढंग से समझता हूं, तो अनुवर्ती डेटाफ्रेम दिया गया है:

df = pd.DataFrame(data={'Seq': [1, 2, 3], 'Dur1': [2, 7, 3],'Val1': ['x', 'y', 'z'],'Dur2': [3, 5, 1], 'Val2': ['a', 'b', 'c']})
    Seq  Dur1 Val1  Dur2 Val2
0    1     2    x     3    a
1    2     7    y     5    b
2    3     3    z     1    c

कोड की ये 5 लाइनें आपकी समस्या का समाधान करती हैं:

dur_col = [col_name for col_name in df.columns if col_name.startswith('Dur')] # ['Dur1', 'Dur2'] 
max_dur_name = df.loc[:, dur_col].max().idxmax()
val_name = "Val" + str([int(s) for s in max_dur_name if s.isdigit()][0])

filter_col = ['Seq', max_dur_name, val_name]

df_res = df[filter_col].sort_values(max_dur_name, ascending=False).head(1)

और आपको मिलता है:

   Seq  Dur1 Val1 
1    2     7    y  

कोड स्पष्टीकरण:

मुझे स्वचालित रूप से वे कॉलम मिलते हैं जो 'डर' से शुरू होते हैं, और मुझे कॉलम नाम लंबी अवधि के साथ मिलता है:

dur_col = [col_name for col_name in df.columns if col_name.startswith('Dur')] # ['Dur1', 'Dur2'] 
max_dur_name = df.loc[:, dur_col].max().idxmax()
val_name = "Val" + str([int(s) for s in max_dur_name if s.isdigit()][0])

उन कॉलमों को चुनें जिनमें मेरी दिलचस्पी है:

filter_col = ['Seq', max_dur_name, val_name]

उन स्तंभों को फ़िल्टर करें जिनमें मेरी रुचि है, मैं max_dur_name लिए आदेश देता max_dur_name और मुझे खोज परिणाम मिलता है:

df_res = df[filter_col].sort_values(max_dur_name, ascending=False).head(1)

# output:
   Seq  Dur1 Val1 
1    2     7    y   

यहाँ एक और तरीका है,

m=df.set_index('Sequence') #set Sequence as index
n=m.filter(like='Duration') #gets all columns with the name Duration
s=n.idxmax()[n.eq(n.values.max()).any()]
#output Duration3    1008
d = dict(zip(m.columns[::2],m.columns[1::2])) #create a mapper dict
#{'Duration1': 'Value1', 'Duration2': 'Value2', 'Duration3': 'Value3'}
final=m.loc[s.values,s.index.union(s.index.map(d))].reset_index()
   Sequence  Duration3  Value3
0      1008        981      82

@ मासिफ़ॉक्स के उत्तर के समान थोड़ा सा, लेकिन मुझे लगता है कि अलग होने के लिए पर्याप्त है।

mvc = df[[name for name in df.columns if 'Duration' in name]].max().idxmax()
mvidx = df[mvc].idxmax()
valuecol = 'Value' + mvc[-1]
df.loc[mvidx, ['Sequence', mvc, valuecol]]
  1. पहले मुझे कॉलम नाम mvc मिलता है जहां अधिकतम मूल्य स्थित है ( mvc आपके उदाहरण के बाद 'Durantion3' )।
  2. तब मुझे अधिकतम मूल्य की पंक्ति सूचकांक mvidx मिलता है ( mvidx 7 )।
  3. फिर मैं सही मान स्तंभ valuecol ( valuecol 'Value3' )।
  4. अंत में loc साथ मैं वांछित आउटपुट का चयन करता हूं, जो है:

    Sequence     1008
    Duration3     981
    Value3         82
    Name: 7, dtype: int64

if len(df[df[dur1]>=df[dur2].max()])==0:
    if len(df[df[dur2]>=df[dur3].max()])==0:
        print(df[df[dur3].idmax()][[seq,dur3,val3]])
    else:
        print(df[df[dur2].idmax()][[seq,dur2,val2]])
else:
   if len(df[df[dur1]>=df[dur3].max()])==0:
       print(df[df[dur3].idmax()][[seq,dur3,val3]])
   else:
       print(df[df[dur1].idmax()][[seq,dur1,val1]])




dataframe