पंडों स्तंभ को NaNs से dtype `int` में बदलें


175

मैं नीचे से पंडों के डेटाफ्रेम के लिए .csv फ़ाइल से डेटा पढ़ता हूं। स्तंभों में से एक के लिए, अर्थात् id, मैं स्तंभ प्रकार निर्दिष्ट करना चाहता हूं int। समस्या यह है कि idश्रृंखला के लापता / खाली मान हैं।

जब मैं id.csv को पढ़ते हुए कॉलम को पूर्णांक में डालने का प्रयास करता हूं, तो मुझे यह मिलता है:

df= pd.read_csv("data.csv", dtype={'id': int}) 
error: Integer column has NA values

वैकल्पिक रूप से, मैंने नीचे के रूप में पढ़ने के बाद कॉलम प्रकार को बदलने की कोशिश की, लेकिन इस बार मुझे मिलता है:

df= pd.read_csv("data.csv") 
df[['id']] = df[['id']].astype(int)
error: Cannot convert NA to integer

मैं इससे कैसे निपट सकता हूं?


3
मुझे लगता है कि यदि अनुपलब्ध / NaN मान हैं, तो पूर्णांक मानों को श्रृंखला / डेटाफ़्रेम में परिवर्तित या संग्रहीत नहीं किया जा सकता है। मुझे लगता है कि मुझे सुपीरियर कम्पैटिबिलिटी के साथ करना है (मैं यहां अनुमान लगा रहा हूं), अगर आप वैल्यू कम्पैटिबिलिटी चाहते हैं तो मैं मानों को फ्लोट्स के रूप में स्टोर
करूंगा

1
यहाँ देखें: pandas.pydata.org/pandas-docs/dev/… ; आपके पास एक फ्लोट dtype होना चाहिए जब u में लापता मान (या तकनीकी रूप से ऑब्जेक्ट dtype लेकिन वह अक्षम हो); int प्रकार का उपयोग करने का आपका लक्ष्य क्या है?
जेफ

6
मेरा मानना ​​है कि यह एक अंक है, जो पंडों के लिए विशिष्ट नहीं है। यह शर्म की बात है क्योंकि वहाँ बहुत सारे मामले हैं जब एक अंतर प्रकार है कि अशक्त मूल्यों की संभावना के लिए अनुमति देता है एक बहुत बड़े स्तंभों की तुलना में कुशल है।
ely

1
मुझे इससे भी समस्या है। मेरे पास कई डेटाफ्रेम हैं जिन्हें मैं कई "पूर्णांक" कॉलमों के स्ट्रिंग प्रतिनिधित्व के आधार पर मर्ज करना चाहता हूं। हालांकि, जब उन पूर्णांक स्तंभों में से एक में np.nan होता है, तो स्ट्रिंग कास्टिंग एक ".0" पैदा करता है, जो मर्ज को फेंक देता है। बस चीजों को थोड़ा और अधिक जटिल बनाता है, अच्छा होगा यदि सरल काम-आस-पास था।
dermen

1
@ रुहर्ब, ऑप्शनल न्युलेबल इंटेगर सपोर्ट अब आधिकारिक तौर पर पांडा 0.24.0 पर जोड़ा गया है - आखिरकार :) - कृपया एक अपडेटेड उत्तर bellow ढूंढें। 0.24.x रिलीज नोट्स पांडा
Mork

जवाबों:


169

पूर्णांक स्तंभों में NaN प्रतिनिधि की कमी एक पांडा "गोत्चा" है

सामान्य वर्कअराउंड केवल फ्लोट्स का उपयोग करना है।


13
क्या उनके पास झांकियों की तरह व्यवहार करने के अलावा कोई अन्य कार्यपट्टी हैं?
न्यूमेरॉर्फ़लाइफ़

3
@ jsc123 आप ऑब्जेक्ट dtype का उपयोग कर सकते हैं। यह एक छोटी स्वास्थ्य चेतावनी के साथ आता है लेकिन अधिकांश भाग अच्छी तरह से काम करता है।
एंडी हेडन

1
क्या आप वस्तु dtype का उपयोग करने का एक उदाहरण प्रदान कर सकते हैं? मैं पांडा डॉक्स और गुग्लिंग के माध्यम से देख रहा हूं, और मैंने पढ़ा है कि यह अनुशंसित विधि है। लेकिन, मुझे इस बात का उदाहरण नहीं मिला है कि ऑब्जेक्ट dtype का उपयोग कैसे करें।
मिकी

29
V0.24 में, अब आप कर सकते हैं df = df.astype(pd.Int32Dtype())(संपूर्ण डेटाफ़्रेम को परिवर्तित करने के लिए, या) df['col'] = df['col'].astype(pd.Int32Dtype())। अन्य स्वीकृत शून्य पूर्णांक प्रकार हैं pd.Int16Dtypeऔर pd.Int64Dtype। अपना ज़हर उठाएं।
cs95

1
यह NaN मान है, लेकिन isnan जाँच बिल्कुल काम नहीं करती :(
Winston

117

संस्करण में 0.24। + पांडा ने लापता मानों के साथ पूर्णांक dtypes रखने की क्षमता प्राप्त की है।

अशक्त पूर्णांक डेटा प्रकार

पंडों पूर्णांक डेटा को संभवतः लापता मानों का उपयोग करके प्रतिनिधित्व कर सकते हैं arrays.IntegerArray। यह एक विस्तार प्रकार है जो पांडा के भीतर लागू किया जाता है। यह पूर्णांकों के लिए डिफ़ॉल्ट dtype नहीं है, और इसका अनुमान नहीं लगाया जाएगा; आपको स्पष्ट रूप से dtype पास करना होगा array()या Series:

arr = pd.array([1, 2, np.nan], dtype=pd.Int64Dtype())
pd.Series(arr)

0      1
1      2
2    NaN
dtype: Int64

स्तंभ को nullable पूर्णांक के उपयोग के लिए परिवर्तित करें:

df['myCol'] = df['myCol'].astype('Int64')

4
मुझे यह उत्तर पसंद है।
cs95

8
ध्यान दें कि dtype होना चाहिए "Int64"और नहीं "int64"(पहले 'i' का कैपिटल होना चाहिए)
Viacheslav Z

2
df.myCol = df.myCol.astype('Int64')याdf['myCol'] = df['myCol'].astype('Int64')
LoMaPh

43

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

df[col] = df[col].fillna(-1)
df[col] = df[col].astype(int)
df[col] = df[col].astype(str)
df[col] = df[col].replace('-1', np.nan)

NaN निकालें, int में कनवर्ट करें, str में कनवर्ट करें और फिर NAN को पुन: स्थापित करें।

यह सुंदर नहीं है, लेकिन यह काम हो जाता है!


1
मैं अपने बालों को खींच रहा हूं, सीरियल नंबर लोड करने की कोशिश कर रहा हूं जहां कुछ अशक्त हैं और बाकी फ्लोट हैं, इसने मुझे बचाया।
क्रिस डेकर

1
ओपी पूर्णांकों का एक स्तंभ चाहता है। इसे स्ट्रिंग में बदलना स्थिति को पूरा नहीं करता है।
ऋषभ गुप्ता

1
केवल तभी काम करता है जब कर्नल के पास पहले से -1 न हो। अन्यथा, यह डेटा के साथ गड़बड़ करेगा
शरवरी Gc

तो फिर इंट से कैसे पाएं .. ??
उदघोष

5

अब NaNs को dtype के रूप में एक पांडा कॉलम बनाना संभव है int, क्योंकि यह अब आधिकारिक तौर पर पांडा 0.24.0 पर जोड़ा गया है

पांडा 0.24.x रिलीज नोट्स उद्धरण: " पंडों ने लापता मूल्यों के साथ पूर्णांक dtypes को धारण करने की क्षमता प्राप्त की है


4

यदि आप पूर्णांक और NaN को एक कॉलम में संयोजित करना चाहते हैं, तो आप 'ऑब्जेक्ट' डेटा प्रकार का उपयोग कर सकते हैं:

df['col'] = (
    df['col'].fillna(0)
    .astype(int)
    .astype(object)
    .where(df['col'].notnull())
)

यह NaNs को एक पूर्णांक (कोई फर्क नहीं पड़ता) के साथ प्रतिस्थापित करेगा, int में कनवर्ट करेगा, ऑब्जेक्ट में कनवर्ट करेगा और अंत में NaN को फिर से करेगा।


3

यदि आप अपने संग्रहीत डेटा को संशोधित कर सकते हैं, तो लापता के लिए एक प्रहरी मूल्य का उपयोग करें id। एक सामान्य उपयोग का मामला, कॉलम नाम से अनुमान लगाया जा रहा है कि idयह एक पूर्णांक है, सख्ती से शून्य से अधिक है, आप 0एक प्रहरी मूल्य के रूप में उपयोग कर सकते हैं ताकि आप लिख सकें

if row['id']:
   regular_process(row)
else:
   special_process(row)

3

यदि आप .dropna()NaN मानों वाली पंक्तियों को छोड़ना ठीक है, तो आप इसका उपयोग कर सकते हैं ।

df = df.dropna(subset=['id'])

वैकल्पिक रूप से, NaN को मानों के साथ बदलने .fillna()और उपयोग .astype()करने और उन्हें int में बदलने के लिए।

बड़े पूर्णांकों के साथ CSV फ़ाइल संसाधित करते समय मैं इस समस्या में भाग गया, जबकि उनमें से कुछ गायब थे (NaN)। फ्लोट का उपयोग करना एक प्रकार का विकल्प नहीं था, क्योंकि मैं परिशुद्धता को ढीला कर सकता हूं।

मेरा समाधान यह था कि इंटर के रूप में स्ट्रैस का उपयोग किया जाए । फिर आप स्ट्रिंग को इंट में बदल सकते हैं जैसे आप बाद में कोड में करते हैं। मैंने NaN को 0 से बदल दिया, लेकिन आप कोई भी मूल्य चुन सकते थे।

df = pd.read_csv(filename, dtype={'id':str})
df["id"] = df["id"].fillna("0").astype(int)

उदाहरण के लिए, यहाँ एक उदाहरण है कि कैसे तैरने से परिशुद्धता ढीली हो सकती है:

s = "12345678901234567890"
f = float(s)
i = int(f)
i2 = int(s)
print (f, i, i2)

और आउटपुट है:

1.2345678901234567e+19 12345678901234567168 12345678901234567890

2

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

keep_df[col] = keep_df[col].apply(lambda x: None if pandas.isnull(x) else '{0:.0f}'.format(pandas.to_numeric(x)))

1

मैं इस मुद्दे पर pyspark के साथ काम करने में भाग गया। चूँकि यह jvm पर चलने वाले कोड के लिए एक अजगर का दृश्य है, इसके लिए टाइप सुरक्षा की आवश्यकता होती है और int के बजाय फ्लोट का उपयोग करना एक विकल्प नहीं है। मैंने pd.read_csvएक फ़ंक्शन में पांडा को लपेटकर इस मुद्दे के चारों ओर काम किया, जो उपयोगकर्ता-परिभाषित कॉलम को उपयोगकर्ता-निर्धारित भरण मूल्यों के साथ उन्हें आवश्यक प्रकार के लिए कास्टिंग करने से पहले भर देगा। यहाँ मैं का उपयोग कर समाप्त हो गया है:

def custom_read_csv(file_path, custom_dtype = None, fill_values = None, **kwargs):
    if custom_dtype is None:
        return pd.read_csv(file_path, **kwargs)
    else:
        assert 'dtype' not in kwargs.keys()
        df = pd.read_csv(file_path, dtype = {}, **kwargs)
        for col, typ in custom_dtype.items():
            if fill_values is None or col not in fill_values.keys():
                fill_val = -1
            else:
                fill_val = fill_values[col]
            df[col] = df[col].fillna(fill_val).astype(typ)
    return df

1
import pandas as pd

df= pd.read_csv("data.csv")
df['id'] = pd.to_numeric(df['id'])

4
क्या कोई कारण है जिसे आप स्वीकार किए गए उत्तर में प्रस्तावित किए गए इस फॉर्मूले को पसंद करते हैं? यदि हां, तो उस स्पष्टीकरण को प्रदान करने के लिए आपके उत्तर को संपादित करना उपयोगी होगा- और विशेष रूप से चूंकि दस अतिरिक्त उत्तर हैं जो ध्यान देने के लिए प्रतिस्पर्धा कर रहे हैं।
जेरेमी कैनी

हालांकि यह कोड ओपी की समस्या को हल कर सकता है, लेकिन स्पष्टीकरण को शामिल करना सबसे अच्छा है कि आपका कोड इसे कैसे / क्यों संबोधित करता है। इस तरह, भविष्य के आगंतुक आपके पोस्ट से सीख सकते हैं, और इसे अपने स्वयं के कोड पर लागू कर सकते हैं। SO एक कोडिंग सेवा नहीं है, बल्कि ज्ञान के लिए एक संसाधन है। इसके अलावा, उच्च गुणवत्ता, पूर्ण उत्तरों के अपग्रेड होने की अधिक संभावना है। ये विशेषताएं, इस आवश्यकता के साथ कि सभी पोस्ट स्व-निहित हैं, एसओ की कुछ ताकतें हैं क्योंकि एक मंच इसे मंचों से अलग करता है। आप editअतिरिक्त जानकारी जोड़ सकते हैं और / या स्रोत प्रलेखन के साथ अपने स्पष्टीकरण को पूरक कर सकते हैं।
शेरलहोमन

0

पहले उन पंक्तियों को हटा दें जिनमें NaN होता है। फिर शेष पंक्तियों पर पूर्णांक रूपांतरण करें। अंतिम बार हटाए गए पंक्तियों को फिर से डालें। आशा है कि यह काम करेगा


-1

अपने DateColumn फॉर्मेट किए गए 3312018.0 को एक स्ट्रिंग के रूप में 03/31/2018 में परिवर्तित किया जाना चाहिए। और, कुछ रिकॉर्ड गायब हैं या 0 हैं।

df['DateColumn'] = df['DateColumn'].astype(int)
df['DateColumn'] = df['DateColumn'].astype(str)
df['DateColumn'] = df['DateColumn'].apply(lambda x: x.zfill(8))
df.loc[df['DateColumn'] == '00000000','DateColumn'] = '01011980'
df['DateColumn'] = pd.to_datetime(df['DateColumn'], format="%m%d%Y")
df['DateColumn'] = df['DateColumn'].apply(lambda x: x.strftime('%m/%d/%Y'))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.