पांडस डेटाफ़्रेम में कोई नहीं के साथ अमान्य मान बदलें


80

क्या Noneपायथन में पंडों के साथ मूल्यों को बदलने की कोई विधि है ?

आप df.replace('pre', 'post')एक मान को दूसरे के साथ उपयोग कर सकते हैं और बदल सकते हैं, लेकिन ऐसा नहीं किया जा सकता है यदि आप Noneमूल्य के साथ प्रतिस्थापित करना चाहते हैं , जो यदि आप कोशिश करते हैं, तो आपको एक अजीब परिणाम मिलता है।

तो यहाँ एक उदाहरण है:

df = DataFrame(['-',3,2,5,1,-5,-1,'-',9])
df.replace('-', 0)

जो एक सफल परिणाम देता है।

परंतु,

df.replace('-', None)

जो निम्नलिखित परिणाम देता है:

0
0   - // this isn't replaced
1   3
2   2
3   5
4   1
5  -5
6  -1
7  -1 // this is changed to `-1`...
8   9

ऐसा अजीब परिणाम क्यों लौटाया जाता है?

चूंकि मैं इस डेटा फ़्रेम को MySQL डेटाबेस में डालना चाहता हूं, इसलिए मैं NaNअपने डेटा फ़्रेम में किसी भी तत्व में मान नहीं डाल सकता और इसके बजाय रखना चाहता हूं None। निश्चित रूप से, आप पहली बार बदल सकते हैं '-'करने के लिए NaNऔर फिर परिवर्तित NaNकरने के लिए None, लेकिन मैं जानना चाहता है कि dataframe इस तरह के एक भयानक तरह से कार्य करता है चाहता हूँ।

पांडा पर परीक्षण 0.12.0 देव पायथन 2.7 और ओएस एक्स 10.8 पर। पायथन OS X पर एक पूर्व-स्थापित संस्करण है और मैंने आपकी जानकारी के लिए SciPy Superpack स्क्रिप्ट का उपयोग करके पांडा स्थापित किया।


क्या write_frameपार्स NaNटू noneएस नहीं है?
एंडी हेडन

हाँ। आप InternalError: (1054, u"Unknown column 'nan' in 'field list'")त्रुटि का सामना करते हैं । मैं विधि को निष्पादित करने NaNसे Noneपहले परिवर्तित करने के अलावा उस पर किसी भी समाधान के बारे में नहीं जानता write_frame
Blaszard

पांडा आप किस संस्करण का उपयोग कर रहे हैं?
एंडी हेडन

डरपोक सुपर पैक बाहर देव देता है? ठीक है, अच्छी तरह से मुझे निश्चित रूप से लगता है कि आपको इसे गितुब पर एक मुद्दे के रूप में उठाना चाहिए, ठीक करने के लिए बहुत मुश्किल नहीं होना चाहिए।
एंडी हेडन

यदि आप CSV / Excel के इस डेटा को पढ़ रहे हैं , तो आप इन मानों को na_valuesतर्क का उपयोग करके NaN के रूप में पढ़ सकते हैं । इस उत्तर में अधिक जानकारी।
cs95

जवाबों:


111

वास्तव में पंडों के बाद के संस्करणों में यह एक टाइपरोर देगा:

df.replace('-', None)
TypeError: If "to_replace" and "value" are both None then regex must be a mapping

आप इसे किसी सूची या शब्दकोश से पास करके कर सकते हैं:

In [11]: df.replace('-', df.replace(['-'], [None]) # or .replace('-', {0: None})
Out[11]:
      0
0  None
1     3
2     2
3     5
4     1
5    -5
6    -1
7  None
8     9

लेकिन मैं किसी के बजाय NaN का उपयोग करने की सलाह देता हूं:

In [12]: df.replace('-', np.nan)
Out[12]:
     0
0  NaN
1    3
2    2
3    5
4    1
5   -5
6   -1
7  NaN
8    9

15
या बस एक सूची, उदाहरण के लिए df.replace(['-'], [None]), या df.replace({'-': None}), मुझे लगता है। Noneएक प्रहरी के रूप में इसका उपयोग मूल्य के रूप में भी करता है।
DSM

@ user2360798 प्रतिस्थापित वास्तव में एक बहुत सुविधा संपन्न (जटिल पढ़ें) फ़ंक्शन है, (देव) डॉकस्ट्रिंग वास्तव में अच्छा है।
एंडी हेडन

4
मुझे नहीं पता कि यह स्पष्ट है, लेकिन dfखुद को वापस सौंपना पड़ा जैसे:df = df.replace({'?': np.nan})
luckyging3r

3
@AndyHayden df.replace('-', df.replace(['-'], [None])फंकी लग रहा है, क्या वह टाइपो है?
lin_bug

2
@lin_bug हालांकि ऐसा लगता है कि हाल के पांडा संस्करणों में अब कोई काम नहीं करता है। df.where (df! = '-', कोई नहीं) काम करता है
एंडी हेडन

17

मैं समाधान का उपयोग पसंद करते हैं replaceएक साथ dictअपनी सादगी और शान की वजह से:

df.replace({'-': None})

आपके पास अधिक प्रतिस्थापन भी हो सकते हैं:

df.replace({'-': None, 'None': None})

और यहां तक ​​कि बड़े प्रतिस्थापनों के लिए, यह हमेशा स्पष्ट और स्पष्ट होता है कि क्या बदला गया है - जो कि लंबी सूची के लिए कठिन है, मेरी राय में।


1
यह ध्यान देने योग्य है कि यह तकनीक क्यों काम करती है इसका एक dictप्रकार यह है कि पैरामीटर का मूल्यांकन न किए जाने के to_replaceकारण होता है method, और इस प्रकार method='pad'डिफ़ॉल्ट का कोई बुरा प्रभाव नहीं पड़ता है।
bsplosion

15

whereशायद वही है जिसकी आपको तलाश है। इसलिए

data=data.where(data=='-', None) 

से पांडा डॉक्स :

where [रिटर्न] स्व के रूप में एक ही आकार की एक वस्तु और जिसकी संबंधित प्रविष्टियां स्वयं से होती हैं जहां कंडोम सही है और अन्यथा अन्य से हैं)।


5
यह वास्तव में गलत है। data = data.where (data == '-', none) कुछ भी बदलेगा जो किसी के साथ '-' के लिए EQUAL नहीं है। पंडों का संस्करण जहां पहले arg का मान रखता है (इस मामले में डेटा == '-'), और दूसरी arg (इस मामले में कोई नहीं) के साथ कुछ और बदलें। यह थोड़ा भ्रामक है क्योंकि np.where अधिक स्पष्ट है कि यह पहले arg में सशर्त पूछता है, फिर यदि दूसरा arg में सही है, तो 3rd arg में गलत है।
clg4

8

इस पद के साथ आगे बढ़ने से पहले, NaN और कोई नहीं के बीच के अंतर को समझना महत्वपूर्ण है । एक फ्लोट प्रकार है, दूसरा ऑब्जेक्ट प्रकार है। पंडाल स्केलर प्रकार के साथ काम करने के लिए बेहतर है क्योंकि इन प्रकारों पर कई तरीकों को वेक्टर किया जा सकता है। पंडों को कोई भी और NaN लगातार संभालने की कोशिश करता है, लेकिन NumPy नहीं कर सकता।

मेरा सुझाव ( और एंडी ) NaN के साथ रहना है।

लेकिन आपके सवाल का जवाब देने के लिए ...

पांडा> = 0.18: के na_values=['-']साथ तर्क का उपयोग करेंread_csv

यदि आपने CSV / Excel से यह डेटा लोड किया है, तो मेरे लिए आपके लिए अच्छी खबर है। आप इसे बाद में चरण के रूप में कोड के साथ फिक्स लिखने के बजाय डेटा लोडिंग के दौरान रूट पर मिटा सकते हैं।

के अधिकांश pd.read_*कार्यों (जैसे read_csvऔर read_excel) एक स्वीकार na_valuesविशेषता।

file.csv

A,B
-,1
3,-
2,-
5,3
1,-2
-5,4
-1,-1
-,0
9,0

अब, -वर्णों को NaN में बदलने के लिए , करें,

import pandas as pd
df = pd.read_csv('file.csv', na_values=['-'])
df

     A    B
0  NaN  1.0
1  3.0  NaN
2  2.0  NaN
3  5.0  3.0
4  1.0 -2.0
5 -5.0  4.0
6 -1.0 -1.0
7  NaN  0.0
8  9.0  0.0

और अन्य फ़ंक्शन / फ़ाइल स्वरूपों के लिए समान है।

PS: v0.24 + पर, आप पूर्णांक प्रकार को संरक्षित कर सकते हैं, भले ही आपके कॉलम में NaN हो (हाँ, केक होने और इसे खाने के बारे में भी बात करें)। आप निर्दिष्ट कर सकते हैंdtype='Int32'

df = pd.read_csv('file.csv', na_values=['-'], dtype='Int32')
df

     A    B
0  NaN    1
1    3  NaN
2    2  NaN
3    5    3
4    1   -2
5   -5    4
6   -1   -1
7  NaN    0
8    9    0

df.dtypes

A    Int32
B    Int32
dtype: object

Dtype एक पारंपरिक इंट प्रकार नहीं है ... बल्कि एक अशक्त पूर्णांक प्रकार है। अन्य विकल्प हैं।


हैंडलिंग संख्यात्मक डेटा: pd.to_numericसाथerrors='coerce

यदि आप संख्यात्मक डेटा के साथ काम कर रहे हैं, pd.to_numericतो errors='coerce'तर्क के साथ उपयोग करने के लिए एक तेज़ समाधान है , जो कि NaN को अमान्य मान (मान जो कि संख्यात्मक को नहीं डाला जा सकता है) को समन्वयित करता है।

pd.to_numeric(df['A'], errors='coerce')

0    NaN
1    3.0
2    2.0
3    5.0
4    1.0
5   -5.0
6   -1.0
7    NaN
8    9.0
Name: A, dtype: float64

(Nullable) पूर्णांक dtype को बनाए रखने के लिए, का उपयोग करें

pd.to_numeric(df['A'], errors='coerce').astype('Int32')

0    NaN
1      3
2      2
3      5
4      1
5     -5
6     -1
7    NaN
8      9
Name: A, dtype: Int32 

कई स्तंभों का उपयोग करने के लिए, उपयोग करें apply:

df[['A', 'B']].apply(pd.to_numeric, errors='coerce').astype('Int32')

     A    B
0  NaN    1
1    3  NaN
2    2  NaN
3    5    3
4    1   -2
5   -5    4
6   -1   -1
7  NaN    0
8    9    0

... और परिणाम के बाद वापस असाइन करें।

इस उत्तर में अधिक जानकारी पाई जा सकती है ।



0

शून्य मान सेट करना निम्न के साथ किया जा सकता है np.nan:

import numpy as np
df.replace('-', np.nan)

फायदा यह है कि df.last_valid_index()इन्हें अमान्य माना जाता है।


0

नए df को प्रतिस्थापित और असाइन करने का उपयोग करना:

import pandas as pd
df = pd.DataFrame(['-',3,2,5,1,-5,-1,'-',9])
dfnew = df.replace('-', 0)
print(dfnew)


(venv) D:\assets>py teste2.py
   0
0  0
1  3
2  2
3  5
4  1
5 -5

0
df.replace('-', np.nan).astype("object")

यह सुनिश्चित करेगा कि आप isnull()अपने डेटाफ़्रेम पर बाद में उपयोग कर सकते हैं


0

पंडों के संस्करण Pand1.0.0 के साथ, मैं उपयोग DataFrame.replaceया Series.replace:

df.replace(old_val, pd.NA, inplace=True)

यह दो कारणों से बेहतर है:

  1. या के pd.NAबजाय इसका उपयोग करता है ।Nonenp.nan
  2. यह इन-प्लेस के स्थान को बदल देता है जो अधिक मेमोरी कुशल हो सकता है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.