एक पांडा डेटाफ़्रेम में पंक्तियों के एक सबसेट को संशोधित करना


143

मान लें कि मेरे पास दो कॉलमों के साथ एक पांडा डेटाफ़्रेम है, ए और बी। मैं इस डेटाफ़्रेम को संशोधित करना चाहता हूं (या एक प्रतिलिपि बनाएं) ताकि बी हमेशा NaN हो जब भी ए 0. है तो मैं इसे कैसे प्राप्त करूंगा?

मैंने निम्नलिखित की कोशिश की

df['A'==0]['B'] = np.nan

तथा

df['A'==0]['B'].values.fill(np.nan)

सफलता के बिना।


यदि आप एक बहुत तेजी से समाधान के लिए देख रहे हैं NumPy के whereरूप में नीचे इस समाधान
टेड पेट्रोउ

जवाबों:


243

.locलेबल आधारित अनुक्रमण के लिए उपयोग करें :

df.loc[df.A==0, 'B'] = np.nan

df.A==0अभिव्यक्ति एक बूलियन श्रृंखला बनाता है कि अनुक्रमित पंक्तियाँ, 'B'स्तंभ का चयन करता है। आप इसका उपयोग कॉलम के सबसेट को बदलने के लिए भी कर सकते हैं, जैसे:

df.loc[df.A==0, 'B'] = df.loc[df.A==0, 'B'] / 2

मुझे पता नहीं है कि पैंडस इंटर्नल के बारे में यह जानने के लिए कि वह क्यों काम करता है, लेकिन मूल मुद्दा यह है कि कभी-कभी डेटाफ्रेम में अनुक्रमण करने से परिणाम की एक प्रति वापस आ जाती है, और कभी-कभी यह मूल वस्तु पर एक दृश्य देता है। यहां प्रलेखन के अनुसार , यह व्यवहार अंतर्निहित सुन्न व्यवहार पर निर्भर करता है। मैंने पाया है कि एक ऑपरेशन में सब कुछ एक्सेस करना ([एक] [दो] के बजाय) सेटिंग के लिए काम करने की अधिक संभावना है।


इसका दूसरा भाग एक ऐसे प्रश्न का एक अच्छा उत्तर है जो पूछा भी नहीं गया था;; मैं सोच रहा हूँ कि क्या यह अभी भी विहित पांडा का उत्तर है, विशेष रूप से b / c में यह एक स्पष्ट DRY उल्लंघन है, हालांकि मुझे लगता है कि इसमें है डीआरवाई का उल्लंघन करने के लिए आवश्यक तथ्य पांडा इंटर्नल्स की बाधाओं को देखते हुए? (मैं इस तरह के प्रश्न को अधिक विस्तार से ठीक-ठीक पोस्ट कर सकता हूं, लेकिन यह देखना चाहता था कि क्या आपके पास ऐसा करने से पहले एक त्वरित उत्तर था)
जॉनी

डेटाफ़्रेम को कैसे कम करें जिसमें कॉलम नाम नहीं हैं, सूचकांक द्वारा डीएफ को कैसे कम करें? df.loc [df [0] == 0] काम नहीं करता ... विकल्प क्या है? धन्यवाद
AmiPro

89

यहां उन्नत अनुक्रमण पर पांडा डॉक्स से है:

अनुभाग आपको जो आवश्यक है वही समझाएगा! टर्न आउट df.loc(as .ix को पदावनत कर दिया गया है - जैसा कि कई ने नीचे इंगित किया है) का उपयोग डेटाफ्रेम की कूलिंग / डायलिंग के लिए किया जा सकता है। तथा। इसका उपयोग चीजों को सेट करने के लिए भी किया जा सकता है।

df.loc[selection criteria, columns I want] = value

तो ब्रेन का जवाब कह रहा है 'मुझे उन सभी जगहों पर खोजें df.A == 0, जहां कॉलम चुनें Bऔर इसे सेट करें np.nan'


2
आपने मेरा दिन बना दिया। स्पष्ट व्याख्या।
ट्विनपेंग्जिन

1
हाँ, किसी तरह loc[selection criteria, columns I want]पूरी तरह से आपके मन से चिपक जाता है ...
EmEs

29

पांडा 0.20 ix से शुरू होता है । सही तरीका df.loc का उपयोग करना है

यहाँ एक कार्य उदाहरण है

>>> import pandas as pd 
>>> import numpy as np 
>>> df = pd.DataFrame({"A":[0,1,0], "B":[2,0,5]}, columns=list('AB'))
>>> df.loc[df.A == 0, 'B'] = np.nan
>>> df
   A   B
0  0 NaN
1  1   0
2  0 NaN
>>> 

स्पष्टीकरण:

जैसा कि यहां डॉक्टर में बताया गया है , .loc मुख्य रूप से लेबल आधारित है, लेकिन इसका उपयोग बूलियन सरणी के साथ भी किया जा सकता है

तो, हम ऊपर क्या कर रहे हैं df.loc[row_index, column_index]द्वारा लागू है:

  • इस तथ्य को उजागर करते हुए कि locहम एक मुखौटा के रूप में बूलियन सरणी ले सकते हैं जो पांडा को बताता है कि पंक्तियों का सबसेट जो हम बदलना चाहते हैंrow_index
  • तथ्य यह है शोषण locभी स्तंभ लेबल का उपयोग कर चयन करने के लिए आधार पर लेबल है 'B'मेंcolumn_index

हम तार्किक, स्थिति या किसी भी ऑपरेशन का उपयोग कर सकते हैं जो बूलियन की श्रृंखला का निर्माण करता है। उपरोक्त उदाहरण में, हम चाहते हैं कि कोई भी rowsहो 0, इसके लिए हम उपयोग कर सकते हैं df.A == 0, जैसा कि आप नीचे दिए गए उदाहरण में देख सकते हैं, यह बूलियंस की एक श्रृंखला देता है।

>>> df = pd.DataFrame({"A":[0,1,0], "B":[2,0,5]}, columns=list('AB'))
>>> df 
   A  B
0  0  2
1  1  0
2  0  5
>>> df.A == 0 
0     True
1    False
2     True
Name: A, dtype: bool
>>> 

फिर, हम आवश्यक पंक्तियों को चुनने और संशोधित करने के लिए बूलियंस के उपरोक्त सरणी का उपयोग करते हैं:

>>> df.loc[df.A == 0, 'B'] = np.nan
>>> df
   A   B
0  0 NaN
1  1   0
2  0 NaN

अधिक जानकारी के लिए यहाँ उन्नत अनुक्रमण प्रलेखन की जाँच करें


11

बड़े पैमाने पर गति बढ़ाने के लिए, NumPy के फ़ंक्शन का उपयोग करें।

सेट अप

कुछ शून्य के साथ 100,000 पंक्तियों के साथ दो-स्तंभ DataFrame बनाएं।

df = pd.DataFrame(np.random.randint(0,3, (100000,2)), columns=list('ab'))

के साथ तेजी से समाधान numpy.where

df['b'] = np.where(df.a.values == 0, np.nan, df.b.values)

समय

%timeit df['b'] = np.where(df.a.values == 0, np.nan, df.b.values)
685 µs ± 6.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df.loc[df['a'] == 0, 'b'] = np.nan
3.11 ms ± 17.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Numpy का where गति लगभग 4x है


मैं इस बारे में उत्सुक था इसलिए मैंने इसे स्वयं परीक्षण किया और अन्य मापदंडों का उपयोग करके अंतर भी अधिक था। Nump.n के बजाय पूर्णांक के साथ 0s को बदलने में Numpy लगभग 10 गुना तेज था। मुझे आश्चर्य है कि अतिरिक्त समय क्या है।
अलेक्जेंडर

इसका इस्तेमाल करने के लिए आवश्यक है .valuesमें np.where(df.a.values == 0, np.nan, df.b.values)? लगता है np.where(df.a == 0, np.nan, df.b)भी काम करता है?
hsl

4

गुणकों के स्तंभों को बदलने के लिए उपयोग करते हुए संख्यात्मक सरणी में बदलें .values:

df.loc[df.A==0, ['B', 'C']] = df.loc[df.A==0, ['B', 'C']].values / 2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.