सशर्त प्रतिस्थापन पंडों


123

मेरे पास एक DataFrame है, और मैं एक विशेष कॉलम में मानों को बदलना चाहता हूं जो शून्य के साथ एक मान से अधिक हो। मैंने सोचा था कि यह इसे प्राप्त करने का एक तरीका था:

df[df.my_channel > 20000].my_channel = 0

अगर मैं चैनल को एक नए डेटा फ्रेम में कॉपी करूँ तो यह सरल है:

df2 = df.my_channel 

df2[df2 > 20000] = 0

यह वही करता है जो मैं चाहता हूं, लेकिन ऐसा लगता है कि चैनल के साथ मूल DataFrame के हिस्से के रूप में काम नहीं कर रहा है।


पाया कि मुझे क्या लगता है कि तुम यहाँ खोज रहे थे ।
फीटवेट

जवाबों:


181

.ixइंडेक्स 0.20.0 से पहले पांडा संस्करण के लिए ठीक काम करता है, लेकिन चूंकि पांडा 0.20.0 है, .ixइंडेक्सर को पदावनत किया जाता है , इसलिए आपको इसका उपयोग करने से बचना चाहिए। इसके बजाय, आप उपयोग .locया ilocअनुक्रमणिका कर सकते हैं । आप इस समस्या को हल कर सकते हैं:

mask = df.my_channel > 20000
column_name = 'my_channel'
df.loc[mask, column_name] = 0

या, एक पंक्ति में,

df.loc[df.my_channel > 20000, 'my_channel'] = 0

maskआपको उन पंक्तियों का चयन करने में मदद करता है जिनमें df.my_channel > 20000है True, जबकि df.loc[mask, column_name] = 0मान को उन चयनित पंक्तियों में 0 सेट करता है जहाँ maskस्तंभ में जो नाम है column_name

अद्यतन: इस मामले में, आपको उपयोग करना चाहिए locक्योंकि यदि आप उपयोग करते हैं iloc, तो आपको एक NotImplementedErrorबताना होगा कि पूर्णांक प्रकार पर iLocation आधारित बूलियन अनुक्रमण उपलब्ध नहीं है


81

प्रयत्न

df.loc[df.my_channel > 20000, 'my_channel'] = 0

नोट: v0.20.0 के बाद से, ix पदावनत किया गया है के पक्ष में loc/ iloc


8
धन्यवाद। मुझे अपना स्वयं का समाधान भी मिला, जो था: df.my_channel [df.my_channel> 20000] = 0
BMichell

2
@ मुझे जो भी लगता है कि आपका समाधान आपको 0.13 में चेतावनी देना शुरू कर सकता है, अभी तक प्रयास करने का मौका नहीं मिला है
19:16 पर

उपज त्रुटि: /opt/anaconda3/envs/python35/lib/python3.5/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning: यह मान किसी DataFrame से एक स्लाइस की प्रतिलिपि पर सेट करने का प्रयास कर रहा है। प्रलेखन: pandas.pydata.org/pandas-docs/stable/… "" "IPython कर्नेल को लॉन्च करने के लिए प्रवेश बिंदु।
रटर होफस्ट

@RutgerHofste का उल्लेख करने के लिए धन्यवाद, अभी तक एक और तर्क पायथन 3 का उपयोग नहीं करता है
लोटेक

34

np.where फ़ंक्शन निम्नानुसार काम करता है:

df['X'] = np.where(df['Y']>=50, 'yes', 'no')

अपने मामले में आप चाहते हैं:

import numpy as np
df['my_channel'] = np.where(df.my_channel > 20000, 0, df.my_channel)

19

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

पंडों की वस्तु में मान स्थापित करते समय, जंजीर अनुक्रमण को क्या कहते हैं, से बचने के लिए सावधानी बरतनी चाहिए।

आपके पास कुछ विकल्प हैं: -

loc + बूलियन अनुक्रमण

loc मूल्यों की स्थापना के लिए इस्तेमाल किया जा सकता है और बूलियन मास्क का समर्थन करता है:

df.loc[df['my_channel'] > 20000, 'my_channel'] = 0

mask + बूलियन अनुक्रमण

आप अपनी श्रृंखला को असाइन कर सकते हैं:

df['my_channel'] = df['my_channel'].mask(df['my_channel'] > 20000, 0)

या आप अपनी श्रृंखला को जगह में अपडेट कर सकते हैं:

df['my_channel'].mask(df['my_channel'] > 20000, 0, inplace=True)

np.where + बूलियन अनुक्रमण

आप कर सकते हैं अपने मूल श्रृंखला जब अपनी हालत है बताए द्वारा NumPy का उपयोग नहीं संतुष्ट; हालाँकि, पहले दो समाधान क्लीनर हैं क्योंकि वे स्पष्ट रूप से केवल निर्दिष्ट मानों को बदलते हैं।

df['my_channel'] = np.where(df['my_channel'] > 20000, 0, df['my_channel'])

0

मैं इस तरह से lambdaफंक्शन का उपयोग करूंगा :SeriesDataFrame

f = lambda x: 0 if x>100 else 1
df['my_column'] = df['my_column'].map(f)

मैं यह नहीं कहता कि यह एक कुशल तरीका है, लेकिन यह ठीक काम करता है।


3
यह अक्षम है और अनुशंसित नहीं है क्योंकि इसमें पंक्ति-वार ऑपरेशन में पायथन-स्तरीय लूप शामिल है।
जेपी

धन्यवाद, मुझे लगता है कि हम locयहां उपयोग कर सकते हैं , जैसे df.loc[: , 'my_column'] = df['my_column'].map(f)। मुझे नहीं पता कि यह तेज है जैसे कि आपने नीचे जोड़ा।
ओजकान सर्क्टास

2
नहीं, अभी भी धीमा है क्योंकि आप अभी भी कॉलम-वार के बजाय पंक्ति-वार चल रहे हैं।
जेपी

0

इसे इस्तेमाल करे:

df.my_channel = df.my_channel.where(df.my_channel <= 20000, other= 0)

या

df.my_channel = df.my_channel.mask(df.my_channel > 20000, other= 0)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.