NumPy या Pandas: NaN मान होने पर सरणी प्रकार को पूर्णांक के रूप में रखते हैं


160

क्या किसी प्रकार के डेटा प्रकार numpyको int(या int64या जो भी) निश्चित रखने का एक पसंदीदा तरीका है , जबकि अभी भी अंदर सूचीबद्ध एक तत्व है numpy.NaN?

विशेष रूप से, मैं एक इन-हाउस डेटा संरचना को पंडों के डेटाफ़्रेम में परिवर्तित कर रहा हूं। हमारी संरचना में, हमारे पास पूर्णांक प्रकार के स्तंभ हैं जिनमें अभी भी NaN है (लेकिन स्तंभ का dtype int है)। यदि हम इसे डेटाफ़्रेम बनाते हैं, तो यह एक फ़्लोट के रूप में सब कुछ पुनर्परिभाषित करता है, लेकिन हम वास्तव में बनना चाहते हैं int

विचार?

कोशिश की गई चीजें:

मैंने from_records()pandas.DataFrame के तहत फंक्शन का उपयोग करने की कोशिश की , coerce_float=Falseइससे मदद नहीं मिली। मैंने NaN fill_value के साथ NumPy नकाबपोश सरणियों का उपयोग करने की भी कोशिश की, जो भी काम नहीं किया। इन सभी के कारण कॉलम डेटा टाइप फ्लोट बन गया।


आप एक नकाबपोश सरणी का उपयोग कर सकते हैं?
mgilson

मै उसे करने की एक कोशिश तो करूंगा। मैंने from_recordsपंडों के साथ फंक्शन की भी कोशिश की। DataFrame, साथ coerce_float=False, लेकिन कोई किस्मत नहीं ... यह अभी भी नया डेटा टाइप करता है float64
ely

1
हाँ, नसीब नहीं। नकाबपोश सरणी के साथ, यह अभी भी फ्लोट में परिवर्तित होता है। ऐसा लग रहा है कि पंडों को इस तरह से जाना जाता है: "क्या कोई NaN कहीं है? ... तो सब कुछ एक नाव है।" उम्मीद है कि इसके चारों ओर एक रास्ता है।
ely

1
वैकल्पिक Nullable पूर्णांक समर्थन अब आधिकारिक तौर पर पांडा 0.24.0 पर जोड़ा गया है - अंत में :) - कृपया एक अद्यतन उत्तर पुस्तिका खोजें। 0.24.x रिलीज नोट्स पांडा
Mork

जवाबों:


70

इस क्षमता को पंडों में जोड़ा गया है (संस्करण 0.24 से शुरू): https://pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-nteger-na-support

इस बिंदु पर, इसे डिफ़ॉल्ट dtype int64 (लोअरकेस) के बजाय एक्सटेंशन dtype Int64 (पूंजीकृत) के उपयोग की आवश्यकता होती है।


1
अभी के लिए आपको एक विशेष dtype निर्दिष्ट करना होगा जैसे 'Int64'कि इसे काम करना। यह तब और बेहतर होगा जब इसे डिफ़ॉल्ट रूप से सक्षम किया जाएगा।
जीन पॉल

यह भी खूब रही! हालांकि एक छोटा सा मुद्दा है कि PyCharm डीबग विंडो में डेटाफ़्रेम प्रदर्शित करने में विफल रहता है अगर इस तरह से उपयोग किया जाता है। आप इसे प्रदर्शित करने के लिए बाध्य करने के लिए एक और प्रश्न के लिए मेरा जवाब देख सकते हैं: stackoverflow.com/questions/38956660/… (मूल समस्या अलग है, लेकिन डेटाफ़्रेम कार्यों को प्रदर्शित करने के लिए समाधान)
आल्हा एम।

क्या मुझे उपयोग करना है 'Int64'या कुछ ऐसा है 'Int8'? यह तुलना में स्मृति की एक पागल राशि का उपयोग करता है np.float
सुपरडोपरेरो

'Int8'काम करने लगता है, लेकिन np.floatअभी भी तेजी से रास्ता लोड हो रहा है। मुद्दा लगता है कि यह स्मृति inbetween जारी नहीं है। मान लें कि कचरा कलेक्टर आखिरकार चलेगा।
Superdooperhero

103

NaNपूर्णांक सरणी में संग्रहीत नहीं किया जा सकता है। यह इस समय पांडा की एक ज्ञात सीमा है; मैं NumPy में NA मानों (R में NAs के समान) के साथ प्रगति की प्रतीक्षा कर रहा हूं, लेकिन NumPy को ये सुविधाएँ मिलने में कम से कम 6 महीने से एक साल पहले का समय लगेगा, ऐसा लगता है:

http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na

(इस सुविधा को पांडा के संस्करण 0.24 के साथ शुरुआत में जोड़ा गया है, लेकिन ध्यान दें कि इसमें डिफ़ॉल्ट dtype int64 (निचला मामला) के बजाय एक्सटेंशन dtype Int64 (पूंजीकृत) के उपयोग की आवश्यकता है: https://pandas.pydata.org/pandas- डॉक्स / संस्करण / 0.24 / whatsnew / v0.24.0.html # वैकल्पिक-पूर्णांक-ना-समर्थन ) सूची


7
हाय वेस, क्या इस पर कोई अपडेट है? हम उन मुद्दों में भाग लेते हैं जो स्तंभों में शामिल होते हैं, उन्हें मूल सूची में NA मान के अस्तित्व के आधार पर या तो इनट या फ़्लोट में परिवर्तित किया जाता है। (इन
डेटाफ्रेम


8

यदि प्रदर्शन मुख्य मुद्दा नहीं है, तो आप इसके बजाय स्ट्रिंग्स को स्टोर कर सकते हैं।

df.col = df.col.dropna().apply(lambda x: str(int(x)) )

फिर आप NaNजितना चाहें उतना मिला सकते हैं। यदि आप वास्तव में पूर्णांक चाहते हैं, तो आपके आवेदन के आधार पर, आप प्रतिनिधित्व करने के लिए उपयोग कर सकते हैं -1, या 0, या 1234567890, या कुछ अन्य समर्पित मूल्य NaN

आप अस्थायी रूप से कॉलम को डुप्लिकेट कर सकते हैं: आपके पास जैसा है, फ्लोट के साथ; अन्य एक प्रयोगात्मक, ints या तार के साथ। फिर assertsहर उचित स्थान पर जाँच करता है कि दोनों सिंक में हैं। पर्याप्त परीक्षण के बाद आप तैरने के लिए जाने दे सकते हैं।


5

यह सभी मामलों के लिए एक समाधान नहीं है, लेकिन मेरा (जीनोमिक निर्देशांक) मैंने 0 का उपयोग NaN के रूप में किया है

a3['MapInfo'] = a3['MapInfo'].fillna(0).astype(int)

यह कम से कम उचित 'देशी' कॉलम प्रकार का उपयोग करने की अनुमति देता है, घटाव, तुलना आदि जैसे ऑपरेशन अपेक्षित रूप से काम करते हैं


5

पंडों v0.24 +

NaNपूर्णांक श्रृंखला में समर्थन के लिए कार्यक्षमता v0.24 में ऊपर की ओर उपलब्ध होगी। नहीं है इस के बारे में जानकारी v0.24 अनुभाग, और के अंतर्गत अधिक विवरण "नया क्या है" में Nullable पूर्णांक डेटा प्रकार

पंडों v0.23 और पहले

सामान्य तौर पर, floatजहां संभव हो, श्रृंखला के साथ काम करना सबसे अच्छा होता है, तब भी जब मूल्यों को शामिल intकरने के floatकारण श्रृंखला से ऊपर उठना होता है NaN। यह वेक्टर-आधारित न्यूपी-आधारित गणनाओं को सक्षम बनाता है, अन्यथा, पायथन-स्तर के छोरों पर कार्रवाई की जाएगी।

डॉक्स सुझाव देते हैं : "एक संभावना dtype=objectइसके बजाय सरणियों का उपयोग करना है।" उदाहरण के लिए:

s = pd.Series([1, 2, 3, np.nan])

print(s.astype(object))

0      1
1      2
2      3
3    NaN
dtype: object

कॉस्मेटिक कारणों से, जैसे फ़ाइल में आउटपुट, यह बेहतर हो सकता है।

पंडों v0.23 और पहले: पृष्ठभूमि

NaNमाना जाता हैfloatडॉक्स वर्तमान में (v0.23) के रूप में क्यों पूर्णांक श्रृंखला के लिए upcasted कर रहे हैं का कारण बताने float:

उच्च प्रदर्शन एनए समर्थन के अभाव में जमीन से NumPy में बनाया जा रहा है, प्राथमिक हताहत पूर्णांक सरणियों में NA का प्रतिनिधित्व करने की क्षमता है।

यह व्यापार बंद बड़े पैमाने पर स्मृति और प्रदर्शन कारणों से किया जाता है, और इसलिए भी कि परिणामी श्रृंखला "संख्यात्मक" बनी हुई है।

डॉक्स भी शामिल किए जाने के कारण अपकास्टिंग के लिए नियम प्रदान करता हैNaN :

Typeclass   Promotion dtype for storing NAs
floating    no change
object      no change
integer     cast to float64
boolean     cast to object

1

यह अब संभव है, चूंकि पांडा v 0.24.0 है

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


1

बस यह जोड़ना चाहते हैं कि यदि आप एक फ्लोट (1.143) वेक्टर को पूर्णांक (1) में बदलने की कोशिश कर रहे हैं जो NA को नए 'Int64' dtype में परिवर्तित कर रहा है तो आपको एक त्रुटि देगा। इसे हल करने के लिए आपको संख्याओं को गोल करना होगा और फिर ".astype ('Int64')"

s1 = pd.Series([1.434, 2.343, np.nan])
#without round() the next line returns an error 
s1.astype('Int64')
#cannot safely cast non-equivalent float64 to int64
##with round() it works
s1.round().astype('Int64')
0      1
1      2
2    NaN
dtype: Int64

मेरा उपयोग मामला यह है कि मेरे पास एक फ़्लोट श्रृंखला है जिसे मैं इंट में राउंड करना चाहता हूं, लेकिन जब आप करते हैं तो नंबर के अंत में .round () 'a * .0' रहता है, इसलिए आप उस 0 को अंत तक छोड़ सकते हैं int में परिवर्तित करना।


0

यदि पाठ डेटा में रिक्त स्थान हैं, तो सामान्य रूप से पूर्णांक वाले स्तंभों को फ़्लोट64 dtype के रूप में फ़्लोट में डाला जाएगा क्योंकि int64 dtype नल को संभाल नहीं सकता है। यह असंगत स्कीमा पैदा कर सकता है यदि आप कई फाइलों को ब्लॉक्स के साथ लोड कर रहे हैं (जो कि फ्लोट64 के रूप में समाप्त हो जाएगा और अन्य बिना जिसके अंत में समाप्त हो जाएगा

यह कोड किसी भी संख्या प्रकार के कॉलम को Int64 में परिवर्तित करने का प्रयास करेगा (int64 के विपरीत) क्योंकि Int64 नल को संभाल सकता है

import pandas as pd
import numpy as np

#show datatypes before transformation
mydf.dtypes

for c in mydf.select_dtypes(np.number).columns:
    try:
        mydf[c] = mydf[c].astype('Int64')
        print('casted {} as Int64'.format(c))
    except:
        print('could not cast {} to Int64'.format(c))

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