If-elif-अन्यथा स्थिति के आधार पर एक नया कॉलम बनाना


103

मेरे पास डेटाफ़्रेम है df:

    A    B
a   2    2 
b   3    1
c   1    3

मैं निम्नलिखित मानदंडों के आधार पर एक नया कॉलम बनाना चाहता हूं:

अगर पंक्ति A == B: 0

अगर पंक्तिA > B: 1

अगर पंक्ति A < B: -1

इसलिए ऊपर दी गई तालिका, यह होनी चाहिए:

    A    B    C
a   2    2    0
b   3    1    1
c   1    3   -1 

if elseमेरे द्वारा किए जाने वाले विशिष्ट मामलों के लिए np.where(df.A > df.B, 1, -1), पांडा एक कदम के साथ मेरी समस्या को हल करने के लिए एक विशेष वाक्यविन्यास प्रदान करता है (3 नए कॉलम बनाने और फिर परिणाम के संयोजन की आवश्यकता के बिना)?


आप बस एक फ़ंक्शन को परिभाषित कर सकते हैं और इसे पास कर सकते हैं applyऔर axis=1काम कर सकते हैं, निश्चित नहीं कि मैं एक ऑपरेशन के बारे में सोच सकता हूं जो आपको वह देगा जो आप चाहते हैं
EdChum

आपका समाधान 3 कॉलम बनाने और उन्हें 1 कॉलम में संयोजित करने का है, या आपके मन में कुछ अलग है?
13

आप "3 कॉलम बना रहे हैं" कहते रहते हैं, लेकिन मुझे यकीन नहीं है कि आप क्या कर रहे हैं।
DSM

1
@DSM ने इस सवाल का जवाब दिया है, लेकिन मेरा मतलब कुछ ऐसा था df['C']=df.apply(myFunc(row), axis=1)जहाँ myFunc आपको क्या चाहिए, इसमें '3 कॉलम' बनाना शामिल नहीं है
EdChum

जवाबों:


152

ऊपर दिए गए कुछ दृष्टिकोणों को औपचारिक रूप देने के लिए:

एक फ़ंक्शन बनाएं जो आपके डेटाफ़्रेम की पंक्तियों पर काम करता है जैसे:

def f(row):
    if row['A'] == row['B']:
        val = 0
    elif row['A'] > row['B']:
        val = 1
    else:
        val = -1
    return val

फिर axis=1विकल्प में पास होने वाली अपनी डेटाफ़्रेम पर लागू करें :

In [1]: df['C'] = df.apply(f, axis=1)

In [2]: df
Out[2]:
   A  B  C
a  2  2  0
b  3  1  1
c  1  3 -1

बेशक, यह सदिश नहीं है, इसलिए जब रिकॉर्ड की एक बड़ी संख्या को बढ़ाया जाता है तो प्रदर्शन उतना अच्छा नहीं हो सकता है। फिर भी, मुझे लगता है कि यह अधिक पठनीय है। विशेष रूप से एसएएस पृष्ठभूमि से आ रहा है।

संपादित करें

यहाँ वेक्टर संस्करण है

df['C'] = np.where(
    df['A'] == df['B'], 0, np.where(
    df['A'] >  df['B'], 1, -1)) 

1
धन्यवाद, मैं पंडों के साथ शुरुआत कर रहा हूं और यह बहुत ही सहायक +1
नौ

4
क्या होगा अगर मैं फ़ंक्शन में पंक्ति के साथ एक और पैरामीटर पास करना चाहता हूं? अगर मैं करता हूं, तो यह कहता है कि पंक्ति परिभाषित नहीं है ..
प्रशान्त मनोहर

3
आपको फंक्शन के argsपैरामीटर का उपयोग .applyकरना होगा: pandas.pydata.org/pandas-docs/stable/generated/…
Zelazny7

1
मैं एक पुराना SAS उपयोगकर्ता हूं जो पायथन सीख रहा है, और निश्चित रूप से सीखने की अवस्था है! :-) उदाहरण के लिए, उपरोक्त कोड एसएएस में लिखा जा सकता है: data df; set df; if A=B then C=0; else if A>B then C=1; else C=-1; run;बहुत सुंदर और सरल।
रॉबर्ट एफएफ

1
एक अच्छी तरह से परिभाषित जवाब
साहिल नागपाल

54
df.loc[df['A'] == df['B'], 'C'] = 0
df.loc[df['A'] > df['B'], 'C'] = 1
df.loc[df['A'] < df['B'], 'C'] = -1

अनुक्रमण का उपयोग करके हल करना आसान है। कोड की पहली पंक्ति इस तरह पढ़ती है, यदि स्तंभ स्तंभ Aके बराबर है , तो 0 के बराबर Bस्तंभ बनाएं और सेट करें C


17

इस विशेष संबंध के लिए, आप इसका उपयोग कर सकते हैं np.sign:

>>> df["C"] = np.sign(df.A - df.B)
>>> df
   A  B  C
a  2  2  0
b  3  1  1
c  1  3 -1

6

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

कहते हैं कि ऊपर वाला आपका मूल डेटाफ़्रेम है और आप एक नया कॉलम 'पुराना' जोड़ना चाहते हैं

यदि उम्र 50 से अधिक है तो हम पुराने = हाँ अन्यथा गलत मानते हैं

चरण 1: उन पंक्तियों के अनुक्रमित प्राप्त करें जिनकी आयु 50 से अधिक है

row_indexes=df[df['age']>=50].index

चरण 2: का उपयोग करके। हम स्तंभ के लिए एक नया मान असाइन कर सकते हैं

df.loc[row_indexes,'elderly']="yes"

50 से कम आयु के लिए समान

row_indexes=df[df['age']<50].index

df[row_indexes,'elderly']="no"


1

जब आपके पास कई if स्थितियां हैं, numpy.selectतो जाने का तरीका है:

In [4102]: import numpy as np
In [4098]: conditions = [df.A.eq(df.B), df.A.gt(df.B), df.A.lt(df.B)]
In [4096]: choices = [0, 1, -1]

In [4100]: df['C'] = np.select(conditions, choices)

In [4101]: df
Out[4101]: 
   A  B  C
a  2  2  0
b  3  1  1
c  1  3 -1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.