पंडों में डेटा प्रकार के कॉलम बदलें


803

मैं सूची में एक सूची के रूप में प्रतिनिधित्व करने वाली तालिका को रूपांतरित करना चाहता हूं Pandas DataFrame। एक अत्यंत सरलीकृत उदाहरण के रूप में:

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a)

स्तंभों को उपयुक्त प्रकारों में परिवर्तित करने का सबसे अच्छा तरीका क्या है, इस मामले में कॉलम 2 और 3 फ्लोट में हैं? क्या डेटाफ़्रेम में कनवर्ट करते समय प्रकार निर्दिष्ट करने का कोई तरीका है? या पहले कॉलम के माध्यम से डेटा को बदलना और फिर कॉलम के माध्यम से लूप बनाना बेहतर है? आदर्श रूप में मैं इसे गतिशील तरीके से करना चाहूंगा क्योंकि सैकड़ों कॉलम हो सकते हैं और मैं यह निर्दिष्ट नहीं करना चाहता कि कौन से कॉलम किस प्रकार के हैं। सभी मैं गारंटी दे सकता हूं कि प्रत्येक कॉलम में एक ही प्रकार के मान शामिल हैं।


मैंने हर कॉलम को बदलने के लिए एप्रोच देखा है और विशेष रूप से नाम वाले कॉलम को एप्रोच किया है, लेकिन एक निश्चित शर्त को पूरा करने वाले कुछ कॉलम के बारे में जब आप 100 कॉलमों को सूचीबद्ध नहीं कर सकते हैं जिन्हें आप एक बार में बदलना चाहते हैं? मैं सभी float64 -> float32 या अन्य मेमोरी सेविंग टैक्टिक्स के उदाहरण के लिए सोच रहा हूं।
डिमांगोलेम

@demongolem: df.apply(pd.to_numeric, downcast="integer", errors="ignore")पूर्णांक स्तंभों को छोटा करने के लिए आप कुछ ऐसा कर सकते हैं जो पूर्णांक (पूर्णांक) dtype का मान रखेगा।
एलेक्स रिले

जवाबों:


1189

पंडों में प्रकार परिवर्तित करने के लिए आपके पास तीन मुख्य विकल्प हैं:

  1. to_numeric()- गैर-संख्यात्मक प्रकार (जैसे तार) को एक उपयुक्त संख्यात्मक प्रकार में परिवर्तित करने के लिए कार्यक्षमता प्रदान करता है। (यह भी देखें to_datetime()और to_timedelta()।)

  2. astype()- (लगभग) किसी भी प्रकार (लगभग) किसी भी अन्य प्रकार में कनवर्ट करें (भले ही ऐसा करने के लिए आवश्यक समझदार न हो)। इसके अलावा आप वर्गीकृत प्रकार (बहुत उपयोगी) में परिवर्तित करने की अनुमति देता है ।

  3. infer_objects() - यदि संभव हो तो पाइथन ऑब्जेक्ट्स को पंडों के प्रकार पर रखने वाले ऑब्जेक्ट कॉलम को परिवर्तित करने के लिए एक उपयोगिता विधि।

इनमें से प्रत्येक विधि के अधिक विस्तृत स्पष्टीकरण और उपयोग के लिए पढ़ें।


1। to_numeric()

किसी DataFrame के एक या अधिक स्तंभों को संख्यात्मक मानों में बदलने का सबसे अच्छा तरीका उपयोग करना है pandas.to_numeric()

यह फ़ंक्शन गैर-संख्यात्मक ऑब्जेक्ट (जैसे स्ट्रिंग्स) को पूर्णांक या फ़्लोटिंग पॉइंट संख्या में उपयुक्त के रूप में बदलने का प्रयास करेगा।

मूल उपयोग

इनपुट to_numeric()एक श्रृंखला या एक DataFrame का एक कॉलम है।

>>> s = pd.Series(["8", 6, "7.5", 3, "0.9"]) # mixed string and numeric values
>>> s
0      8
1      6
2    7.5
3      3
4    0.9
dtype: object

>>> pd.to_numeric(s) # convert everything to float values
0    8.0
1    6.0
2    7.5
3    3.0
4    0.9
dtype: float64

जैसा कि आप देख सकते हैं, एक नई श्रृंखला वापस आ गई है। इसे जारी रखने के लिए एक चर या स्तंभ नाम पर इस आउटपुट को असाइन करना याद रखें:

# convert Series
my_series = pd.to_numeric(my_series)

# convert column "a" of a DataFrame
df["a"] = pd.to_numeric(df["a"])

आप apply()विधि के माध्यम से DataFrame के कई कॉलम को परिवर्तित करने के लिए भी इसका उपयोग कर सकते हैं :

# convert all columns of DataFrame
df = df.apply(pd.to_numeric) # convert all columns of DataFrame

# convert just columns "a" and "b"
df[["a", "b"]] = df[["a", "b"]].apply(pd.to_numeric)

जब तक आपके मूल्यों को सभी में परिवर्तित किया जा सकता है, तब तक शायद यही आपकी आवश्यकता है।

गलती संभालना

लेकिन क्या होगा यदि कुछ मानों को संख्यात्मक प्रकार में परिवर्तित नहीं किया जा सकता है?

to_numeric()एक errorsकीवर्ड तर्क भी लेता है जो आपको गैर-संख्यात्मक मानों को बाध्य करने की अनुमति देता है NaN, या बस इन मूल्यों वाले कॉलमों को अनदेखा करता है।

यहां एक श्रृंखला का उपयोग करके एक उदाहरण sदिया गया है, जिसमें वस्तु dtype है:

>>> s = pd.Series(['1', '2', '4.7', 'pandas', '10'])
>>> s
0         1
1         2
2       4.7
3    pandas
4        10
dtype: object

यदि यह मान नहीं बदल सकता है तो डिफ़ॉल्ट व्यवहार को ऊपर उठाना है। इस स्थिति में, यह स्ट्रिंग 'पांडा' का सामना नहीं कर सकता:

>>> pd.to_numeric(s) # or pd.to_numeric(s, errors='raise')
ValueError: Unable to parse string

असफल होने के बजाय, हम चाहते हैं कि 'पांडा' को एक लापता / खराब संख्यात्मक मान माना जाए। हम कीवर्ड तर्क NaNका उपयोग करते हुए अमान्य मानों को ले errorsसकते हैं:

>>> pd.to_numeric(s, errors='coerce')
0     1.0
1     2.0
2     4.7
3     NaN
4    10.0
dtype: float64

errorsयदि अमान्य मान सामने आया है, तो ऑपरेशन को अनदेखा करने का तीसरा विकल्प है:

>>> pd.to_numeric(s, errors='ignore')
# the original Series is returned untouched

यह अंतिम विकल्प विशेष रूप से तब उपयोगी होता है जब आप अपना पूरा डेटाफ़्रेम बदलना चाहते हैं, लेकिन यह नहीं जानते हैं कि हमारे कौन से कॉलमों को मज़बूती से एक संख्यात्मक प्रकार में परिवर्तित किया जा सकता है। उस मामले में बस लिखें:

df.apply(pd.to_numeric, errors='ignore')

फ़ंक्शन को DataFrame के प्रत्येक कॉलम पर लागू किया जाएगा। उन स्तंभों को एक संख्यात्मक प्रकार में परिवर्तित किया जा सकता है, जबकि उन कॉलमों को परिवर्तित नहीं किया जा सकता है (उदाहरण के लिए उनमें गैर-अंकों के तार या तिथियां शामिल हैं) अकेले छोड़ दिए जाएंगे।

downcasting

डिफ़ॉल्ट रूप से, के साथ रूपांतरण to_numeric()या तो आप एक दे देंगे int64या float64dtype (या जो भी पूर्णांक चौड़ाई अपने मंच के मूल निवासी है)।

यह आमतौर पर आप क्या चाहते हैं, लेकिन क्या होगा अगर आप कुछ मेमोरी को बचाना चाहते थे और एक अधिक कॉम्पैक्ट dtype का उपयोग करना चाहते थे, जैसे float32, या int8?

to_numeric()आपको 'पूर्णांक', 'हस्ताक्षरित', 'अहस्ताक्षरित', 'फ्लोट' को डाउनकास्ट करने का विकल्प देता है। यहाँ sपूर्णांक प्रकार की एक सरल श्रृंखला के लिए एक उदाहरण दिया गया है :

>>> s = pd.Series([1, 2, -7])
>>> s
0    1
1    2
2   -7
dtype: int64

'पूर्णांक' के लिए डाउनकास्टिंग सबसे छोटे संभव पूर्णांक का उपयोग करता है जो मूल्यों को धारण कर सकता है:

>>> pd.to_numeric(s, downcast='integer')
0    1
1    2
2   -7
dtype: int8

'फ्लोट' को डाउनकास्टिंग करना सामान्य फ्लोटिंग प्रकार की तुलना में छोटा होता है:

>>> pd.to_numeric(s, downcast='float')
0    1.0
1    2.0
2   -7.0
dtype: float32

2। astype()

यह astype()विधि आपके डेटाफ़्रेम या श्रृंखला के लिए इच्छित dtype के बारे में स्पष्ट होने में सक्षम बनाती है। यह बहुत बहुमुखी है कि आप एक प्रकार से किसी भी अन्य में जाने की कोशिश कर सकते हैं।

मूल उपयोग

बस एक प्रकार चुनें: आप एक NumPy dtype (जैसे np.int16), कुछ पायथन प्रकार (जैसे बूल), या पांडा-विशिष्ट प्रकार (जैसे श्रेणीबद्ध dtype) का उपयोग कर सकते हैं।

उस ऑब्जेक्ट पर विधि को कॉल करें जिसे आप कनवर्ट करना चाहते हैं astype()और आपके लिए इसे बदलने और बदलने की कोशिश करेंगे:

# convert all DataFrame columns to the int64 dtype
df = df.astype(int)

# convert column "a" to int64 dtype and "b" to complex type
df = df.astype({"a": int, "b": complex})

# convert Series to float16 type
s = s.astype(np.float16)

# convert Series to Python strings
s = s.astype(str)

# convert Series to categorical type - see docs for more details
s = s.astype('category')

सूचना मैंने कहा "कोशिश" - अगर astype()यह नहीं जानता कि श्रृंखला या डेटाफ़्रेम में किसी मूल्य को कैसे परिवर्तित किया जाए, तो यह एक त्रुटि उठाएगा। उदाहरण के लिए यदि आपके पास एक NaNया infमान है, तो आपको एक पूर्णांक में बदलने की कोशिश में एक त्रुटि मिलेगी।

पांडा 0.20.0 के रूप में, इस त्रुटि को पारित करके दबाया जा सकता है errors='ignore'। आपकी मूल वस्तु वापस लौट आएगी।

सावधान रहे

astype()शक्तिशाली है, लेकिन यह कभी-कभी मूल्यों को "गलत तरीके" में बदल देगा। उदाहरण के लिए:

>>> s = pd.Series([1, 2, -7])
>>> s
0    1
1    2
2   -7
dtype: int64

ये छोटे पूर्णांक हैं, इसलिए स्मृति को बचाने के लिए एक अहस्ताक्षरित 8-बिट प्रकार में कैसे परिवर्तित किया जाए?

>>> s.astype(np.uint8)
0      1
1      2
2    249
dtype: uint8

रूपांतरण ने काम किया, लेकिन -7 249 (यानी 2 8 - 7) बनने के लिए गोल लपेट दिया गया था !

pd.to_numeric(s, downcast='unsigned')इसके बजाय डाउनकास्ट का उपयोग करने से इस त्रुटि को रोकने में मदद मिल सकती है।


3। infer_objects()

पंडों के संस्करण 0.21.0 ने infer_objects()एक DataFrame के स्तंभों को परिवर्तित करने के लिए विधि पेश की, जिसमें एक वस्तु विशिष्ट प्रकार के अधिक विशिष्ट प्रकार (सॉफ्ट रूपांतरण) के लिए है।

उदाहरण के लिए, यहां ऑब्जेक्ट प्रकार के दो कॉलम के साथ एक DataFrame है। एक वास्तविक पूर्णांक रखता है और दूसरा पूर्णांक का प्रतिनिधित्व करता है:

>>> df = pd.DataFrame({'a': [7, 1, 5], 'b': ['3','2','1']}, dtype='object')
>>> df.dtypes
a    object
b    object
dtype: object

उपयोग करके infer_objects(), आप कॉलम 'a' के प्रकार को int64 में बदल सकते हैं:

>>> df = df.infer_objects()
>>> df.dtypes
a     int64
b    object
dtype: object

कॉलम 'बी' को अकेला छोड़ दिया गया है क्योंकि इसके मूल्य स्ट्रिंग थे, पूर्णांक नहीं। यदि आप दोनों स्तंभों के रूपांतरण को पूर्णांक प्रकार से करने का प्रयास करना चाहते हैं, तो आप df.astype(int)इसके बजाय उपयोग कर सकते हैं ।


8
इसके अलावा, .astype (फ्लोट) के विपरीत, यह स्ट्रिंग को एक त्रुटि बढ़ाने के बजाय NaNs में बदल देगा
Rob

11
.convert_objectsके बाद से हटा दिया गया है 0.17- df.to_numericइसके बजाय का उपयोग करें
मत्ती

4
धन्यवाद - मुझे इस उत्तर को अपडेट करना चाहिए। यह शायद ध्यान देने योग्य है कि pd.to_numericऔर इसके साथी तरीके केवल एक समय में, इसके विपरीत एक कॉलम पर काम करेंगे convert_objects। एपीआई में एक प्रतिस्थापन समारोह के बारे में चर्चा चल रही है ; मुझे आशा है कि एक विधि जो पूरे DataFrame पर काम करती है वह बनी रहेगी क्योंकि यह बहुत उपयोगी है।
एलेक्स रिले

सबसे अच्छा तरीका है कि आप वर्तमान में कहे जाने वाले सभी स्तंभों को रूपांतरित int64करें int32?
RoyalTS

4
@RoyalTS: शायद सबसे अच्छा उपयोग करने के लिए astype(अन्य उत्तर में), यानी .astype(numpy.int32)
एलेक्स रिले

447

इस बारे में कैसा है?

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['one', 'two', 'three'])
df
Out[16]: 
  one  two three
0   a  1.2   4.2
1   b   70  0.03
2   x    5     0

df.dtypes
Out[17]: 
one      object
two      object
three    object

df[['two', 'three']] = df[['two', 'three']].astype(float)

df.dtypes
Out[19]: 
one       object
two      float64
three    float64

10
हाँ! pd.DataFrameएक dtypeतर्क है जो आपको w / दे सकता है आप खोज रहे हैं। df = pd.DataFrame (a, column = ['one', 'two', 'three'], dtype = float) [2] में: df.dtypes Out [2]: एक ऑब्जेक्ट दो float64 तीन float64 dtype: ऑब्जेक्ट
हरनामसरबारा

17
जब मैं सुझाव के अनुसार प्रयास करता हूं, तो मुझे चेतावनी मिलती है SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead। यह पंडों के एक नए संस्करण में पेश किया गया है और मुझे इसके परिणामस्वरूप कुछ भी गलत नहीं दिख रहा है, लेकिन मुझे आश्चर्य है कि यह चेतावनी क्या है। कोई उपाय?
नारंगी

2
@orange चेतावनी उपयोगकर्ताओं को संभावित रूप से जंजीरों के संचालन के साथ भ्रमित करने वाले व्यवहार के लिए सतर्क करने के लिए है, और पंडों के साथ डेटाफ़्रेम को संपादित करने की बजाय प्रतियां वापस कर रही है। stackoverflow.com/questions/20625582/… और संबंधित देखें ।
१.२14

19
यह एक अच्छा तरीका है, लेकिन यह तब काम नहीं करता है जब एक कॉलम में NaN हो। पता नहीं क्यों NaN सिर्फ NaN नहीं रह सकता है जब कास्टिंग int करने के लिए तैरना:ValueError: Cannot convert NA to integer
विटाली इसा

7
@GillBates हाँ, एक शब्दकोश में। df = pd.DataFrame(a, columns=['one', 'two', 'three'], dtype={'one': str, 'two': int, 'three': float})। हालांकि मुझे "dtype" मानों के लिए विनिर्देश खोजने में कठिन समय हो रहा है। एक सूची अच्छी होगी (वर्तमान में मैं करता हूं dict(enumerate(my_list)))।
फिच्तेफॉल

39

यह नीचे दिया गया कोड कॉलम का डेटाटाइप बदल देगा।

df[['col.name1', 'col.name2'...]] = df[['col.name1', 'col.name2'..]].astype('data_type')

डेटा टाइप के स्थान पर आप अपना डेटाटाइप दे सकते हैं। आप क्या चाहते हैं जैसे स्ट्र, फ्लोट, इंट आदि।


आपको यह ध्यान में रखें कि जब तार पर यह लागू किया जाता है, जिसमें `` '' सही '`` `और` `` `' 'गलत है,` `डेटा_टाइप का उपयोग करके bool, सब कुछ बदल जाता है True
एच। वबरी

यह विकल्प आप टाइप भी कर सकते हैं "श्रेणी"
neves

17

जब मुझे केवल विशिष्ट कॉलम निर्दिष्ट करने की आवश्यकता होती है, और मैं स्पष्ट होना चाहता हूं, तो मैंने उपयोग किया है (प्रति दस्तावेज स्थिति ):

dataframe = dataframe.astype({'col_name_1':'int','col_name_2':'float64', etc. ...})

इसलिए, मूल प्रश्न का उपयोग करते हुए, लेकिन इसे कॉलम नाम प्रदान करना ...

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['col_name_1', 'col_name_2', 'col_name_3'])
df = df.astype({'col_name_2':'float64', 'col_name_3':'float64'})

15

यहाँ एक फ़ंक्शन है जो अपने तर्कों को एक DataFrame और स्तंभों की एक सूची के रूप में लेता है और स्तंभों में सभी डेटा को संख्याओं में जमा करता है।

# df is the DataFrame, and column_list is a list of columns as strings (e.g ["col1","col2","col3"])
# dependencies: pandas

def coerce_df_columns_to_numeric(df, column_list):
    df[column_list] = df[column_list].apply(pd.to_numeric, errors='coerce')

तो, आपके उदाहरण के लिए:

import pandas as pd

def coerce_df_columns_to_numeric(df, column_list):
    df[column_list] = df[column_list].apply(pd.to_numeric, errors='coerce')

a = [['a', '1.2', '4.2'], ['b', '70', '0.03'], ['x', '5', '0']]
df = pd.DataFrame(a, columns=['col1','col2','col3'])

coerce_df_columns_to_numeric(df, ['col2','col3'])

क्या होगा यदि आप कॉलम नामों के बजाय कॉलम इंडेक्स का उपयोग करना चाहते हैं?
ज्वलंति

8

कैसे दो डेटाफ़्रेम बनाने के बारे में, प्रत्येक अपने कॉलम के लिए अलग-अलग डेटा प्रकारों के साथ, और फिर उन्हें एक साथ जोड़कर?

d1 = pd.DataFrame(columns=[ 'float_column' ], dtype=float)
d1 = d1.append(pd.DataFrame(columns=[ 'string_column' ], dtype=str))

परिणाम

In[8}:  d1.dtypes
Out[8]: 
float_column     float64
string_column     object
dtype: object

डेटाफ्रेम तैयार होने के बाद, आप इसे 1 कॉलम में फ्लोटिंग पॉइंट वैरिएबल और 2 कॉलम में स्ट्रिंग्स (या कोई भी डेटा टाइप इच्छा) के साथ पॉप्युलेट कर सकते हैं।


4

पांडा> = 1.0

यहाँ एक चार्ट है जो पांडा के सबसे महत्वपूर्ण रूपांतरणों में से कुछ को सारांशित करता है।

यहां छवि विवरण दर्ज करें

स्ट्रिंग के लिए रूपांतरण तुच्छ हैं .astype(str)और आंकड़े में नहीं दिखाए गए हैं।

"हार्ड" बनाम "सॉफ्ट" रूपांतरण

ध्यान दें कि इस संदर्भ में "रूपांतरण" या तो पाठ डेटा को उनके वास्तविक डेटा प्रकार (हार्ड रूपांतरण) में परिवर्तित करने, या ऑब्जेक्ट कॉलम (सॉफ्ट रूपांतरण) में डेटा के लिए अधिक उपयुक्त डेटा प्रकारों का संदर्भ दे सकता है। अंतर को स्पष्ट करने के लिए, एक नज़र डालें

df = pd.DataFrame({'a': ['1', '2', '3'], 'b': [4, 5, 6]}, dtype=object)
df.dtypes                                                                  

a    object
b    object
dtype: object

# Actually converts string to numeric - hard conversion
df.apply(pd.to_numeric).dtypes                                             

a    int64
b    int64
dtype: object

# Infers better data types for object data - soft conversion
df.infer_objects().dtypes                                                  

a    object  # no change
b     int64
dtype: object

# Same as infer_objects, but converts to equivalent ExtensionType
df.convert_dtypes().dtypes                                                     

1

मुझे लगा कि मेरे पास भी यही समस्या है लेकिन वास्तव में मेरे पास थोड़ा अंतर है जिससे समस्या को हल करना आसान हो जाता है। इस प्रश्न को देखने वाले अन्य लोगों के लिए यह आपकी इनपुट सूची के प्रारूप की जाँच करने के लायक है। मेरे मामले में संख्या शुरू में तैरती नहीं है जैसा कि सवाल में नहीं है:

a = [['a', 1.2, 4.2], ['b', 70, 0.03], ['x', 5, 0]]

लेकिन सूची को संसाधित करने से पहले डेटाफ़्रेम बनाने से पहले मैं प्रकार खो देता हूं और सब कुछ एक स्ट्रिंग बन जाता है।

एक संख्यात्मक सरणी के माध्यम से डेटा फ्रेम बनाना

df = pd.DataFrame(np.array(a))

df
Out[5]: 
   0    1     2
0  a  1.2   4.2
1  b   70  0.03
2  x    5     0

df[1].dtype
Out[7]: dtype('O')

प्रश्न में समान डेटा फ्रेम देता है, जहां कॉलम 1 और 2 में प्रविष्टियों को स्ट्रिंग माना जाता है। हालांकि कर रहे हैं

df = pd.DataFrame(a)

df
Out[10]: 
   0     1     2
0  a   1.2  4.20
1  b  70.0  0.03
2  x   5.0  0.00

df[1].dtype
Out[11]: dtype('float64')

वास्तव में सही प्रारूप में कॉलम के साथ एक डेटा फ्रेम देता है


0

पंडों की शुरुआत 1.0.0, हमारे पास है pandas.DataFrame.convert_dtypes। आप यह भी नियंत्रित कर सकते हैं कि किस प्रकार को रूपांतरित करना है!

In [40]: df = pd.DataFrame(
    ...:     {
    ...:         "a": pd.Series([1, 2, 3], dtype=np.dtype("int32")),
    ...:         "b": pd.Series(["x", "y", "z"], dtype=np.dtype("O")),
    ...:         "c": pd.Series([True, False, np.nan], dtype=np.dtype("O")),
    ...:         "d": pd.Series(["h", "i", np.nan], dtype=np.dtype("O")),
    ...:         "e": pd.Series([10, np.nan, 20], dtype=np.dtype("float")),
    ...:         "f": pd.Series([np.nan, 100.5, 200], dtype=np.dtype("float")),
    ...:     }
    ...: )

In [41]: dff = df.copy()

In [42]: df 
Out[42]: 
   a  b      c    d     e      f
0  1  x   True    h  10.0    NaN
1  2  y  False    i   NaN  100.5
2  3  z    NaN  NaN  20.0  200.0

In [43]: df.dtypes
Out[43]: 
a      int32
b     object
c     object
d     object
e    float64
f    float64
dtype: object

In [44]: df = df.convert_dtypes()

In [45]: df.dtypes
Out[45]: 
a      Int32
b     string
c    boolean
d     string
e      Int64
f    float64
dtype: object

In [46]: dff = dff.convert_dtypes(convert_boolean = False)

In [47]: dff.dtypes
Out[47]: 
a      Int32
b     string
c     object
d     string
e      Int64
f    float64
dtype: object
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.