पंडों: मैं एक कॉलम के लिए आवेदन () फ़ंक्शन का उपयोग कैसे कर सकता हूं?


254

मेरे पास दो कॉलम के साथ एक पांडा डेटा फ्रेम है। मुझे दूसरे कॉलम को प्रभावित किए बिना पहले कॉलम के मूल्यों को बदलने की ज़रूरत है और पूरे डेटा फ़्रेम को वापस लौटाएं जिसमें पहले कॉलम के मान बदल गए हों। पांडा में लागू करने का उपयोग मैं कैसे कर सकता हूं?


4
कृपया कुछ इनपुट नमूना डेटा और वांछित आउटपुट पोस्ट करें।
फाबियो लामना

आपको applyइस तरह की स्थिति में लगभग कभी भी उपयोग नहीं करना चाहिए । इसके बजाय सीधे कॉलम पर काम करें।
टेड पेट्रोउ

जैसा कि टेड पेट्रोव ने कहा, applyजितना संभव हो उतना उपयोग करने से बचें । यदि आप सुनिश्चित नहीं हैं कि आपको इसका उपयोग करने की आवश्यकता है, तो आप संभवतः नहीं। मेरा सुझाव है कि मुझे अपने कोड में पंडों को लागू करने () का उपयोग कब करना चाहिए?
cs95

प्रश्न पूरी तरह से स्पष्ट नहीं है: क्या यह स्तंभ के प्रत्येक तत्व के लिए एक फ़ंक्शन लागू करता है या स्तंभ पर फ़ंक्शन को पूरे के रूप में लागू करता है (उदाहरण के लिए: स्तंभ को उल्टा करें)?
पियरे ALBARÈDE

जवाबों:


336

एक नमूना डेटाफ़्रेम के dfरूप में दिया गया:

a,b
1,2
2,3
3,4
4,5

आप क्या चाहते हैं:

df['a'] = df['a'].apply(lambda x: x + 1)

वह रिटर्न:

   a  b
0  2  2
1  3  3
2  4  4
3  5  5

9
applyइस तरह की स्थिति में कभी भी इस्तेमाल नहीं किया जाना चाहिए
टेड पेट्रो

5
@TedPetrou आप पूरी तरह से सही हैं, यह सिर्फ एक उदाहरण है कि एक एकल कॉलम पर एक सामान्य फ़ंक्शन कैसे लागू किया जाए, जैसा कि ओपी ने पूछा था।
फाबियो लमन्ना

14
जब मैं ऐसा करने की कोशिश करता हूं तो मुझे निम्नलिखित चेतावनी मिलती है: "डेटाफ़्रेम से एक स्लाइस की एक प्रति पर एक मूल्य सेट करने की कोशिश की जा रही है। उपयोग करने की कोशिश करें। इसके बजाय .loc [row_indexer, col_indexer] = मान दें"
dagrun

24
जिज्ञासा के रूप में: उस स्थिति में आवेदन क्यों नहीं किया जाना चाहिए? वास्तव में स्थिति क्या है?
अंकल बेन बेन

19
@UncleBenBen सामान्य रूप applyसे पंक्तियों पर एक आंतरिक लूप का उपयोग करता है जो कि वेक्टरकृत कार्यों की तुलना में बहुत धीमा है, जैसे कि df.a = df.a / 2(माइक मुलर उत्तर देखें)।
फाबियो लामन्ना

66

map()इस तरह से उपयोग करने के लिए बेहतर एक एकल स्तंभ के लिए :

df = pd.DataFrame([{'a': 15, 'b': 15, 'c': 5}, {'a': 20, 'b': 10, 'c': 7}, {'a': 25, 'b': 30, 'c': 9}])

    a   b  c
0  15  15  5
1  20  10  7
2  25  30  9



df['a'] = df['a'].map(lambda a: a / 2.)

      a   b  c
0   7.5  15  5
1  10.0  10  7
2  12.5  30  9

78
एक कॉलम के लिए क्यों map()बेहतर है apply()?
चैमग

2
यह बहुत उपयोगी था। मैंने इसका उपयोग कॉलम में संग्रहीत पथों से फ़ाइल नाम निकालने के लिए किया थाdf['file_name'] = df['Path'].map(lambda a: os.path.basename(a))
mmann1123

46
मैप () श्रृंखला (यानी एकल कॉलम) के लिए है और एक बार में एक सेल पर काम करता है, जबकि लागू () डेटाफ़्रेम के लिए है, और एक समय में पूरी पंक्ति पर काम करता है।
jpcgt

3
@jpcgt क्या इसका मतलब यह है कि इस मामले में आवेदन की तुलना में नक्शा तेज है?
विराग ० Vir १19

@ChaimG मैं देख रहा हूँ कि यह ओएस अच्छी तरह से समझाता है: stackoverflow.com/a/19798528/571828

40

आप एक समारोह की जरूरत नहीं है। आप सीधे पूरे कॉलम पर काम कर सकते हैं।

उदाहरण डेटा:

>>> df = pd.DataFrame({'a': [100, 1000], 'b': [200, 2000], 'c': [300, 3000]})
>>> df

      a     b     c
0   100   200   300
1  1000  2000  3000

स्तंभ के सभी मान आधे a:

>>> df.a = df.a / 2
>>> df

     a     b     c
0   50   200   300
1  500  2000  3000

क्या होगा यदि मैं प्रत्येक तत्व को "/" द्वारा एक कॉलम में विभाजित करना चाहता हूं और पहला भाग ले सकता हूं?
K47

12

यद्यपि दी गई प्रतिक्रियाएं सही हैं, वे प्रारंभिक डेटा फ़्रेम को संशोधित करते हैं, जो हमेशा वांछनीय नहीं होता है (और, ओपी को "उपयोग करते हुए apply" उदाहरण के लिए कहा जाता है , यह हो सकता है कि वे एक ऐसा संस्करण चाहते थे जो एक नया डेटा फ़्रेम लौटाए, जैसा कि applyकरता है)।

इसका उपयोग संभव है assign: यह assignमौजूदा कॉलमों के लिए मान्य है , क्योंकि प्रलेखन राज्य (जोर मेरा है):

DataFrame में नए कॉलम असाइन करें।

नए के अलावा सभी मूल स्तंभों के साथ एक नई वस्तु लौटाता है। मौजूदा कॉलम जो फिर से असाइन किए गए हैं, उन्हें ओवरराइट किया जाएगा

संक्षेप में:

In [1]: import pandas as pd

In [2]: df = pd.DataFrame([{'a': 15, 'b': 15, 'c': 5}, {'a': 20, 'b': 10, 'c': 7}, {'a': 25, 'b': 30, 'c': 9}])

In [3]: df.assign(a=lambda df: df.a / 2)
Out[3]: 
      a   b  c
0   7.5  15  5
1  10.0  10  7
2  12.5  30  9

In [4]: df
Out[4]: 
    a   b  c
0  15  15  5
1  20  10  7
2  25  30  9

ध्यान दें कि फ़ंक्शन को संपूर्ण डेटाफ़्रेम पास किया जाएगा, न केवल उस कॉलम को जिसे आप संशोधित करना चाहते हैं, इसलिए आपको यह सुनिश्चित करने की आवश्यकता होगी कि आप अपने लैम्ब्डा में सही कॉलम का चयन करें।


9

यदि आप वास्तव में अपने लागू फ़ंक्शन की निष्पादन गति के बारे में चिंतित हैं और आपके पास काम करने के लिए एक बड़ा डेटासेट है, तो आप तेजी से निष्पादन करने के लिए स्विफ्टर का उपयोग कर सकते हैं, यहां पंडों के डेटाफ्रेम पर स्विफ्टर के लिए एक उदाहरण है:

import pandas as pd
import swifter

def fnc(m):
    return m*3+4

df = pd.DataFrame({"m": [1,2,3,4,5,6], "c": [1,1,1,1,1,1], "x":[5,3,6,2,6,1]})

# apply a self created function to a single column in pandas
df["y"] = df.m.swifter.apply(fnc)

यह आपके सभी सीपीयू कोर को परिणाम की गणना करने में सक्षम करेगा इसलिए यह सामान्य लागू कार्यों की तुलना में बहुत तेज होगा। कोशिश करें और मुझे बताएं कि क्या यह आपके लिए उपयोगी है।


1

मुझे डेटाइम का उपयोग करके और रिक्त स्थान या रिक्त स्थान पर विचार करते हुए एक जटिल गणना की कोशिश करें। मैं एक डेटाइम कॉलम पर 30 साल कम कर रहा हूं और applyसाथ ही विधि का उपयोग कर रहा हूं lambdaऔर डेटाटाइम प्रारूप को परिवर्तित कर रहा हूं । रेखा if x != '' else xअपने अनुसार सभी खाली जगहों या नल की देखभाल करेगी।

df['Date'] = df['Date'].fillna('')
df['Date'] = df['Date'].apply(lambda x : ((datetime.datetime.strptime(str(x), '%m/%d/%Y') - datetime.timedelta(days=30*365)).strftime('%Y%m%d')) if x != '' else x)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.