पांडा का उपयोग करते हुए दो कॉलम की तुलना करें


104

इसे शुरुआती बिंदु के रूप में उपयोग करना:

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

Out[8]: 
  one  two three
0   10  1.2   4.2
1   15  70   0.03
2    8   5     0

मैं ifपंडों के भीतर एक बयान की तरह कुछ का उपयोग करना चाहता हूं ।

if df['one'] >= df['two'] and df['one'] <= df['three']:
    df['que'] = df['one']

मूल रूप से, ifकथन के माध्यम से प्रत्येक पंक्ति की जांच करें , नया कॉलम बनाएं।

डॉक्स का उपयोग करने के लिए कहते हैं, .allलेकिन कोई उदाहरण नहीं है ...


यदि ifकथन है तो मूल्य क्या होना चाहिए False?
एलेक्स रिले

3
@ मर्लिन: यदि आपके पास एक कॉलम में संख्यात्मक डेटा है, तो इसे स्ट्रिंग्स के साथ मिश्रण नहीं करना सबसे अच्छा है। ऐसा करने से कॉलम का dtype बदल जाता है object। यह पाइथन वस्तुओं को मनमाने ढंग से कॉलम में संग्रहित करने की अनुमति देता है, लेकिन यह धीमी सांख्यिक गणना की लागत पर आता है। इस प्रकार यदि स्तंभ संख्यात्मक डेटा संग्रहीत कर रहा है, तो संख्याओं के लिए NaN का उपयोग करना बेहतर होता है।
अनटुब

1
तार के रूप में पूर्णांक होने और उन पर तुलना करने की कोशिश करना अजीब लगता है a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]:। यह "सही" कोड के साथ भ्रामक परिणाम पैदा करता है: पहली पंक्ति के लिए df['que'] = df['one'][(df['one'] >= df['two']) & (df['one'] <= df['three'])] पैदावार 10, जबकि यह चाहिए NaNअगर इनपुट पूर्णांक होता।
प्राइमर

जवाबों:


147

आप np.where का उपयोग कर सकते हैं । तो condएक बूलियन सरणी है, और Aऔर Bसरणियों, तो कर रहे हैं

C = np.where(cond, A, B)

सी को परिभाषित करता है Aकि condयह कहां तक सही है और Bकहां condगलत है।

import numpy as np
import pandas as pd

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

df['que'] = np.where((df['one'] >= df['two']) & (df['one'] <= df['three'])
                     , df['one'], np.nan)

पैदावार

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03  NaN
2   8    5     0  NaN

यदि आपके पास एक से अधिक स्थितियां हैं, तो आप इसके बजाय np.select का उपयोग कर सकते हैं । उदाहरण के लिए, यदि आप df['que']समान df['two']होने की इच्छा रखते हैं df['one'] < df['two'], तो

conditions = [
    (df['one'] >= df['two']) & (df['one'] <= df['three']), 
    df['one'] < df['two']]

choices = [df['one'], df['two']]

df['que'] = np.select(conditions, choices, default=np.nan)

पैदावार

  one  two three  que
0  10  1.2   4.2   10
1  15   70  0.03   70
2   8    5     0  NaN

अगर हम यह मान सकते हैं कि df['one'] >= df['two']कब df['one'] < df['two']गलत है, तो शर्तों और विकल्पों को सरल बनाया जा सकता है

conditions = [
    df['one'] < df['two'],
    df['one'] <= df['three']]

choices = [df['two'], df['one']]

(इस धारणा अगर सच नहीं हो सकता df['one']या df['two']Nans होते हैं।)


ध्यान दें कि

a = [['10', '1.2', '4.2'], ['15', '70', '0.03'], ['8', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])

स्ट्रिंग मानों के साथ एक DataFrame परिभाषित करता है। चूंकि वे संख्यात्मक दिखते हैं, इसलिए आप उन स्ट्रिंग्स को फ़्लोट में परिवर्तित करना बेहतर हो सकते हैं:

df2 = df.astype(float)

यह परिणाम बदलता है, हालांकि, चूंकि तार चरित्र-दर-वर्ण की तुलना करते हैं, जबकि फ्लोट की तुलना संख्यात्मक रूप से की जाती है।

In [61]: '10' <= '4.2'
Out[61]: True

In [62]: 10 <= 4.2
Out[62]: False

72

आप .equalsकॉलम या संपूर्ण डेटाफ़्रेम के लिए उपयोग कर सकते हैं ।

df['col1'].equals(df['col2'])

यदि वे बराबर हैं, कि बयान वापस आ जाएगी Trueऔर को, False


22
नोट: यह केवल पूरे कॉलम की तुलना दूसरे से करता है। यह उपनिवेशवादी तत्व की तुलना नहीं करता है
गेरुआ

1
कैसे के बारे में अगर आप देखना चाहते हैं कि क्या एक कॉलम हमेशा "से अधिक" या "अन्य स्तंभों की तुलना में कम" है?
rrlamichhane

28

आप आवेदन () का उपयोग कर सकते हैं और ऐसा कुछ कर सकते हैं

df['que'] = df.apply(lambda x : x['one'] if x['one'] >= x['two'] and x['one'] <= x['three'] else "", axis=1)

या यदि आप लैम्बडा का उपयोग नहीं करना पसंद करते हैं

def que(x):
    if x['one'] >= x['two'] and x['one'] <= x['three']:
        return x['one']
    return ''
df['que'] = df.apply(que, axis=1)

2
मुझे संदेह है कि यह पोस्ट किए गए अन्य तरीकों की तुलना में शायद थोड़ा धीमा है, क्योंकि यह उन सदिश संचालन का लाभ नहीं उठाता है जो पांडा अनुमति देता है।
मेरीस

@ याकूबफेनर: लैम्ब्डा पढ़ने योग्य नहीं हैं जब जटिल का उपयोग करते हैं यदि / फिर / फिर अन्य कथन।
मर्लिन

@ मर्लिन आप एक और जोड़ सकते हैं और मैं आपके साथ लंबोदर और कई स्थितियों पर सहमत होऊंगा
बॉब हैफनर

क्या नॉन लैम्ब्डा फ़ंक्शन को सामान्य करने का एक तरीका है कि आप डेटाफ़्रेम कॉलम पास कर सकते हैं और नाम नहीं बदल सकते?
अज़ाहो

@ याहाओ आप इस df ['que'] = df.apply (lambda x: x.iloc [0] अगर x.iloc [0]> = x.iloc [1] और x.iloc [0] की तरह iloc के साथ सामान्यीकरण कर सकते हैं ] <= x.iloc [2] और "", अक्ष = 1) क्या आपका मतलब है? जाहिर है। आपके स्तंभ के मामले का क्रम
बॉब हैफनर

9

स्तंभ को अनुक्रमित करने के लिए एक बूलियन श्रृंखला का उपयोग करने का एक तरीका है df['one']। यह आपको एक नया कॉलम देता है, जहां Trueप्रविष्टियों का मूल्य उसी पंक्ति के समान होता है जैसे df['one']और Falseमान होते हैंNaN

बूलियन श्रृंखला सिर्फ आपके ifबयान द्वारा दी गई है (हालांकि इसके &बजाय इसका उपयोग करना आवश्यक है and):

>>> df['que'] = df['one'][(df['one'] >= df['two']) & (df['one'] <= df['three'])]
>>> df
    one two three   que
0   10  1.2 4.2      10
1   15  70  0.03    NaN
2   8   5   0       NaN

यदि आप चाहते हैं कि NaNमानों को अन्य मानों द्वारा प्रतिस्थापित किया जाए, तो आप fillnaनए कॉलम पर विधि का उपयोग कर सकते हैं que। मैंने 0यहां खाली स्ट्रिंग के बजाय उपयोग किया है:

>>> df['que'] = df['que'].fillna(0)
>>> df
    one two three   que
0   10  1.2   4.2    10
1   15   70  0.03     0
2    8    5     0     0

4

कोष्ठकों में प्रत्येक व्यक्तिगत स्थिति को लपेटें, और फिर &शर्तों को संयोजित करने के लिए ऑपरेटर का उपयोग करें :

df.loc[(df['one'] >= df['two']) & (df['one'] <= df['three']), 'que'] = df['one']

आप ~मैच का उल्टा करने के लिए ("नहीं" ऑपरेटर) का उपयोग करके गैर-मिलान वाली पंक्तियों को भर सकते हैं :

df.loc[~ ((df['one'] >= df['two']) & (df['one'] <= df['three'])), 'que'] = ''

आपको उपयोग करने की बजाय &और करने की आवश्यकता ~है andऔर notक्योंकि &और ~ऑपरेटर तत्व-दर-तत्व काम करते हैं।

अंतिम परिणाम:

df
Out[8]: 
  one  two three que
0  10  1.2   4.2  10
1  15   70  0.03    
2   8    5     0  

1

का प्रयोग करें np.selectयदि आप कई की स्थिति एक अलग कॉलम में dataframe और उत्पादन एक विशिष्ट विकल्प से जांच की जानी है

conditions=[(condition1),(condition2)]
choices=["choice1","chocie2"]

df["new column"]=np.select=(condtion,choice,default=)

नोट: कोई भी स्थिति और विकल्पों में से कोई भी मेल नहीं खाना चाहिए, यदि आपके पास एक ही विकल्प है, तो दो अलग-अलग स्थितियों में पाठ को दोहराएं


0

मुझे लगता है कि ओपी के अंतर्ज्ञान के सबसे करीब अगर कोई कथन है तो इनलाइन:

df['que'] = (df['one'] if ((df['one'] >= df['two']) and (df['one'] <= df['three'])) 

आपका कोड मुझे त्रुटि देता हैdf['que'] = (df['one'] if ((df['one'] >= df['two']) and (df['one'] <= df['three'])) ^ SyntaxError: unexpected EOF while parsing
vasili111
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.