python - पांडा में कॉलम का नाम बदलना




pandas replace (16)

एक लाइन या पाइपलाइन समाधान

मैं दो चीजों पर ध्यान केंद्रित करूंगा:

  1. ओपी स्पष्ट रूप से बताता है

    मेरे पास संपादित कॉलम नाम एक सूची में संग्रहीत हैं, लेकिन मुझे नहीं पता कि कॉलम नामों को कैसे बदला जाए।

    मैं '$' को प्रतिस्थापित करने या प्रत्येक कॉलम हेडर के पहले वर्ण को बंद करने की समस्या को हल नहीं करना चाहता हूं। ओपी पहले से ही यह कदम उठा चुका है। इसके बजाय मैं मौजूदा columns ऑब्जेक्ट को प्रतिस्थापन कॉलम नामों की एक सूची के साथ एक नए के साथ बदलने पर ध्यान केंद्रित करना चाहता हूं।

  2. df.columns = new जहां new कॉलम नामों की सूची नई है जितनी सरल हो जाती है। इस दृष्टिकोण की कमी यह है कि इसे मौजूदा डेटाफ्रेम के columns विशेषता को संपादित करने की आवश्यकता है और यह इनलाइन नहीं किया गया है। मैं मौजूदा डेटा फ्रेम को संपादित किए बिना पाइपलाइनिंग के माध्यम से इसे करने के कुछ तरीके दिखाऊंगा।

सेटअप 1
पूर्व-मौजूदा सूची के साथ कॉलम नामों को प्रतिस्थापित करने की आवश्यकता पर ध्यान केंद्रित करने के लिए, मैं प्रारंभिक कॉलम नामों और असंबंधित नए कॉलम नामों के साथ एक नया नमूना डेटाफ्रेम df तैयार करूंगा।

df = pd.DataFrame({'Jack': [1, 2], 'Mahesh': [3, 4], 'Xin': [5, 6]})
new = ['x098', 'y765', 'z432']

df

   Jack  Mahesh  Xin
0     1       3    5
1     2       4    6

समाधान 1
pd.DataFrame.rename

यह पहले से ही कहा गया है कि यदि आपके पास पुराने कॉलम नामों को नए कॉलम नामों में मैपिंग करने वाला शब्दकोश था, तो आप pd.DataFrame.rename उपयोग कर सकते हैं।

d = {'Jack': 'x098', 'Mahesh': 'y765', 'Xin': 'z432'}
df.rename(columns=d)

   x098  y765  z432
0     1     3     5
1     2     4     6

हालांकि, आप आसानी से उस शब्दकोश को बना सकते हैं और इसे rename लिए कॉल में शामिल कर सकते हैं। निम्नलिखित इस तथ्य का लाभ उठाते हैं कि जब df पर पुनरावृत्ति होती है, तो हम प्रत्येक कॉलम नाम पर फिर से सक्रिय होते हैं।

# given just a list of new column names
df.rename(columns=dict(zip(df, new)))

   x098  y765  z432
0     1     3     5
1     2     4     6

यदि आपके मूल कॉलम नाम अद्वितीय हैं तो यह बहुत अच्छा काम करता है। लेकिन अगर वे नहीं हैं, तो यह टूट जाता है।

सेटअप 2
गैर अद्वितीय कॉलम

df = pd.DataFrame(
    [[1, 3, 5], [2, 4, 6]],
    columns=['Mahesh', 'Mahesh', 'Xin']
)
new = ['x098', 'y765', 'z432']

df

   Mahesh  Mahesh  Xin
0       1       3    5
1       2       4    6

समाधान 2
keys तर्क का उपयोग कर pd.concat

सबसे पहले, ध्यान दें कि जब हम समाधान 1 का उपयोग करने का प्रयास करते हैं तो क्या होता है:

df.rename(columns=dict(zip(df, new)))

   y765  y765  z432
0     1     3     5
1     2     4     6

हमने कॉलम नाम के रूप में new सूची को मैप नहीं किया। हम y765 दोहराया समाप्त हो गया। इसके बजाए, हम df के कॉलम के माध्यम से pd.concat फ़ंक्शन की keys तर्क का उपयोग कर सकते हैं।

pd.concat([c for _, c in df.items()], axis=1, keys=new) 

   x098  y765  z432
0     1     3     5
1     2     4     6

समाधान 3
फिर से संगठित। इसका उपयोग केवल तभी किया जाना चाहिए जब आपके पास सभी कॉलम के लिए एक ही प्रकार का dtype । अन्यथा, आप सभी कॉलम के लिए dtype object साथ समाप्त हो dtype और उन्हें वापस परिवर्तित करने के लिए और अधिक शब्दकोश काम की आवश्यकता होगी।

एकल dtype

pd.DataFrame(df.values, df.index, new)

   x098  y765  z432
0     1     3     5
1     2     4     6

मिश्रित dtype

pd.DataFrame(df.values, df.index, new).astype(dict(zip(new, df.dtypes)))

   x098  y765  z432
0     1     3     5
1     2     4     6

समाधान 4
यह transpose और set_index साथ एक set_index चाल है। pd.DataFrame.set_index हमें एक इंडेक्स इनलाइन सेट करने की अनुमति देता है लेकिन कोई संबंधित set_columns । तो हम set_index कर सकते हैं, फिर set_index , और वापस set_index कर सकते हैं। हालांकि, समाधान 3 से मिश्रित dtype dtype बनाम एक ही एकल प्रकार dtype यहां लागू होता है।

एकल dtype

df.T.set_index(np.asarray(new)).T

   x098  y765  z432
0     1     3     5
1     2     4     6

मिश्रित dtype

df.T.set_index(np.asarray(new)).T.astype(dict(zip(new, df.dtypes)))

   x098  y765  z432
0     1     3     5
1     2     4     6

समाधान 5
pd.DataFrame.rename में एक lambda प्रयोग करें जो new तत्व के प्रत्येक चक्र के माध्यम से चक्र
इस समाधान में, हम एक लैम्ब्डा पास करते हैं जो x लेता है लेकिन फिर इसे अनदेखा करता है। यह एक y भी लेता है लेकिन इसकी उम्मीद नहीं करता है। इसके बजाए, एक इटरेटर को डिफ़ॉल्ट मान के रूप में दिया जाता है और फिर मैं उस समय एक के माध्यम से एक के माध्यम से चक्र के लिए x के मूल्य के संबंध में उपयोग कर सकता हूं।

df.rename(columns=lambda x, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6

और जैसा कि मैंने सोपीथॉन चैट में लोगों द्वारा इंगित किया है, अगर मैं x और y बीच में * जोड़ता हूं, तो मैं अपने y चर को सुरक्षित रख सकता हूं। हालांकि, इस संदर्भ में मुझे विश्वास नहीं है कि इसे सुरक्षा की जरूरत है। यह अभी भी उल्लेखनीय लायक है।

df.rename(columns=lambda x, *, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6

मेरे पास पांडा और कॉलम लेबल का उपयोग करके डेटाफ्रेम है जिसे मुझे मूल कॉलम लेबल को प्रतिस्थापित करने के लिए संपादित करने की आवश्यकता है।

मैं डेटाफ्रेम A में कॉलम नामों को बदलना चाहता हूं जहां मूल कॉलम नाम हैं:

['$a', '$b', '$c', '$d', '$e'] 

सेवा मेरे

['a', 'b', 'c', 'd', 'e'].

मेरे पास संपादित कॉलम नाम एक सूची में संग्रहीत हैं, लेकिन मुझे नहीं पता कि कॉलम नामों को कैसे बदला जाए।


कॉलम नाम बनाम श्रृंखला के नाम

मैं दृश्यों के पीछे क्या होता है, इसकी व्याख्या करना चाहता हूं।

डेटाफ्रेम श्रृंखला का एक सेट है।

बदले में श्रृंखला एक numpy.array का विस्तार है

numpy.array पास एक संपत्ति है .name

यह श्रृंखला का नाम है। यह शायद ही कभी है कि पांडा इस विशेषता का सम्मान करते हैं, लेकिन यह जगहों पर आते हैं और कुछ पांडा व्यवहारों को हैक करने के लिए इस्तेमाल किया जा सकता है।

स्तंभों की सूची का नामकरण

यहां बहुत सारे उत्तर df.columns विशेषता के बारे में बात करते हैं, जब वास्तव में यह एक Series । इसका मतलब है कि इसमें एक .name विशेषता है।

यदि आप कॉलम का नाम भरने का निर्णय लेते हैं तो यह होता है:

df.columns = ['column_one', 'column_two']
df.columns.names = ['name of the list of columns']
df.index.names = ['name of the index']

name of the list of columns     column_one  column_two
name of the index       
0                                    4           1
1                                    5           2
2                                    6           3

ध्यान दें कि इंडेक्स का नाम हमेशा एक कॉलम कम आता है।

कलाकृतियों जो रेंगते हैं

कई बार .name विशेषता .name । यदि आप df.columns = ['one', 'two'] तो df.one.name 'one'

यदि आप df.one.name = 'three' सेट df.one.name = 'three' तो df.columns आपको अभी भी ['one', 'two'] , और df.one.name आपको 'three'

परंतु

pd.DataFrame(df.one) वापस आ जाएगा

    three
0       1
1       2
2       3

क्योंकि पांडा पहले से परिभाषित Series के .name का .name उपयोग करते हैं।

मल्टी लेवल कॉलम नाम

पांडों के पास बहु स्तरित कॉलम नाम करने के तरीके हैं। इसमें इतना जादू शामिल नहीं है लेकिन मैं इसे अपने उत्तर में भी कवर करना चाहता था क्योंकि मुझे यह देखने में कोई भी नहीं दिख रहा है।

    |one            |
    |one      |two  |
0   |  4      |  1  |
1   |  5      |  2  |
2   |  6      |  3  |

यह सूची में कॉलम सेट करके आसानी से प्राप्त किया जा सकता है, इस तरह:

df.columns = [['one', 'one'], ['one', 'two']]

पांडस 0.21+ उत्तर

संस्करण 0.21 में कॉलम नामकरण के लिए कुछ महत्वपूर्ण अपडेट हुए हैं।

  • rename विधि ने axis पैरामीटर जोड़ा है जो columns या 1 सेट किया जा सकता है। यह अद्यतन इस विधि को शेष पांडा एपीआई से मेल खाता है। इसमें अभी भी index और columns पैरामीटर हैं लेकिन अब आप उनका उपयोग करने के लिए मजबूर नहीं हैं।
  • set_axis सेट पर सेट के साथ set_axis विधि आपको सूची के साथ सभी इंडेक्स या कॉलम लेबल्स का नाम बदलने में सक्षम बनाती है।

पांडस 0.21+ के लिए उदाहरण

नमूना डेटा फ्रेम का निर्माण करें:

df = pd.DataFrame({'$a':[1,2], '$b': [3,4], 
                   '$c':[5,6], '$d':[7,8], 
                   '$e':[9,10]})

   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

axis='columns' या axis=1 साथ rename का उपयोग करना

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis='columns')

या

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis=1)

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

   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10

पुराने विधि हस्ताक्षर का उपयोग करना अभी भी संभव है:

df.rename(columns={'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'})

नामकरण फ़ंक्शन उन कार्यों को भी स्वीकार करता है जो प्रत्येक कॉलम नाम पर लागू होंगे।

df.rename(lambda x: x[1:], axis='columns')

या

df.rename(lambda x: x[1:], axis=1)

एक सूची और inplace=False साथ set_axis का उपयोग करना

आप set_axis विधि में एक सूची प्रदान कर सकते हैं जो स्तंभों (या अनुक्रमणिका) की लंबाई के बराबर है। वर्तमान में, inplace True डिफ़ॉल्ट है, लेकिन inplace भविष्य में रिलीज में False हो जाएगा।

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis='columns', inplace=False)

या

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis=1, inplace=False)

df.columns = ['a', 'b', 'c', 'd', 'e'] उपयोग क्यों न करें?

कॉलम को इस तरह सीधे निर्दिष्ट करने में कुछ भी गलत नहीं है। यह एक बिल्कुल अच्छा समाधान है।

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

# new for pandas 0.21+
df.some_method1()
  .some_method2()
  .set_axis()
  .some_method3()

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()

असली सरल बस उपयोग करें

df.columns = ['Name1', 'Name2', 'Name3'...]

और यह कॉलम नामों को आपके द्वारा दिए गए क्रम से असाइन करेगा


इसे इस्तेमाल करे। इससे मेरा काम बनता है

df.rename(index=str, columns={"$a": "a", "$b": "b", "$c" : "c", "$d" : "d", "$e" : "e"})

चूंकि आप केवल सभी कॉलम नामों में $ साइन को हटाना चाहते हैं, तो आप बस ऐसा कर सकते हैं:

df = df.rename(columns=lambda x: x.replace('$', ''))

या

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)

ध्यान दें कि ये दृष्टिकोण मल्टीइंडेक्स के लिए काम नहीं करते हैं। मल्टीइंडेक्स के लिए, आपको निम्न की तरह कुछ करने की आवश्यकता है:

>>> df = pd.DataFrame({('$a','$x'):[1,2], ('$b','$y'): [3,4], ('e','f'):[5,6]})
>>> df
   $a $b  e
   $x $y  f
0  1  3  5
1  2  4  6
>>> rename = {('$a','$x'):('a','x'), ('$b','$y'):('b','y')}
>>> df.columns = pandas.MultiIndex.from_tuples([
        rename.get(item, item) for item in df.columns.tolist()])
>>> df
   a  b  e
   x  y  f
0  1  3  5
1  2  4  6

बस इसे .columns विशेषता को असाइन करें:

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20

मुझे लगता है कि यह विधि उपयोगी है:

df.rename(columns={"old_column_name1":"new_column_name1", "old_column_name2":"new_column_name2"})

यह विधि आपको कॉलम नामों को व्यक्तिगत रूप से बदलने की अनुमति देती है।


मूल कॉलम लेबल को प्रतिस्थापित करने का एक और तरीका मूल स्तंभ लेबल से अवांछित वर्ण (यहां '$') को अलग करना है।

यह df.columns पर लूप चलाने और df.columns को पट्टी वाले कॉलम को जोड़कर किया जा सकता था।

इसके बजाए, हम नीचे दी गई सूची समझ का उपयोग करके एक ही कथन में यह अच्छी तरह से कर सकते हैं:

df.columns = [col.strip('$') for col in df.columns]

(पायथन में strip विधि स्ट्रिंग के आरंभ और अंत से दिए गए चरित्र को स्ट्रिप्स करती है।)


यदि आपके पास डेटाफ्रेम है, तो df.columns सबकुछ उस सूची में डंप करता है जिसे आप जोड़ सकते हैं और फिर कॉलम के नाम के रूप में अपने डेटाफ्रेम में फिर से असाइन कर सकते हैं ...

columns = df.columns
columns = [row.replace("$","") for row in columns]
df.rename(columns=dict(zip(columns, things)), inplace=True)
df.head() #to validate the output

सबसे अच्छा तरीका? IDK। एक रास्ता - हाँ।

सवाल के जवाब में आगे रखी गई सभी मुख्य तकनीकों का मूल्यांकन करने का एक बेहतर तरीका सीपीरोफाइल का उपयोग करके गेज मेमोरी और निष्पादन समय तक है। @kadee, @kaitlyn, और @eumiro के पास सबसे तेज़ निष्पादन समय के साथ कार्य था - हालांकि ये कार्य इतनी तेजी से हैं कि हम सभी उत्तरों के लिए .000 और .001 सेकंड के गोलाकार की तुलना कर रहे हैं। नैतिक: संभवतः मेरा उत्तर 'सर्वश्रेष्ठ' तरीका नहीं है।

import pandas as pd
import cProfile, pstats, re

old_names = ['$a', '$b', '$c', '$d', '$e']
new_names = ['a', 'b', 'c', 'd', 'e']
col_dict = {'$a': 'a', '$b': 'b','$c':'c','$d':'d','$e':'e'}

df = pd.DataFrame({'$a':[1,2], '$b': [10,20],'$c':['bleep','blorp'],'$d':[1,2],'$e':['texa$','']})

df.head()

def eumiro(df,nn):
    df.columns = nn
    #This direct renaming approach is duplicated in methodology in several other answers: 
    return df

def lexual1(df):
    return df.rename(columns=col_dict)

def lexual2(df,col_dict):
    return df.rename(columns=col_dict, inplace=True)

def Panda_Master_Hayden(df):
    return df.rename(columns=lambda x: x[1:], inplace=True)

def paulo1(df):
    return df.rename(columns=lambda x: x.replace('$', ''))

def paulo2(df):
    return df.rename(columns=lambda x: x.replace('$', ''), inplace=True)

def migloo(df,on,nn):
    return df.rename(columns=dict(zip(on, nn)), inplace=True)

def kadee(df):
    return df.columns.str.replace('$','')

def awo(df):
    columns = df.columns
    columns = [row.replace("$","") for row in columns]
    return df.rename(columns=dict(zip(columns, '')), inplace=True)

def kaitlyn(df):
    df.columns = [col.strip('$') for col in df.columns]
    return df

print 'eumiro'
cProfile.run('eumiro(df,new_names)')
print 'lexual1'
cProfile.run('lexual1(df)')
print 'lexual2'
cProfile.run('lexual2(df,col_dict)')
print 'andy hayden'
cProfile.run('Panda_Master_Hayden(df)')
print 'paulo1'
cProfile.run('paulo1(df)')
print 'paulo2'
cProfile.run('paulo2(df)')
print 'migloo'
cProfile.run('migloo(df,old_names,new_names)')
print 'kadee'
cProfile.run('kadee(df)')
print 'awo'
cProfile.run('awo(df)')
print 'kaitlyn'
cProfile.run('kaitlyn(df)')

यदि आपको अपने नियंत्रण से बाहर प्रणाली प्रदान करने वाले कॉलम के भार से निपटना है, तो मैं निम्नलिखित दृष्टिकोण के साथ आया हूं जो एक सामान्य दृष्टिकोण और विशिष्ट प्रतिस्थापन का संयोजन है।

मैं पहले कॉलम नामों के कुछ परिशिष्टों को फेंकने के लिए रेगेक्स अभिव्यक्तियों का उपयोग करके डेटाफ्रेम कॉलम नामों से एक शब्दकोश बनाता हूं और फिर मैं प्राप्तकर्ता डेटाबेस में बाद में कोर कॉलम नाम देने के लिए शब्दकोश में विशिष्ट प्रतिस्थापन जोड़ता हूं।

इसके बाद डेटाफ्रेम पर एक बार में लागू किया जाता है।

dict=dict(zip(df.columns,df.columns.str.replace('(:S$|:C1$|:L$|:D$|\.Serial:L$)','')))
dict['brand_timeseries:C1']='BTS'
dict['respid:L']='RespID'
dict['country:C1']='CountryID
dict['pim1:D']='pim_actual'
df.rename(columns=dict, inplace=True)

df.rename() फ़ंक्शन का उपयोग करें और कॉलम का नाम बदलकर देखें। सभी कॉलम का नाम बदलना नहीं है:

df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})
# Or rename the existing DataFrame (rather than creating a copy) 
df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'}, inplace=True)

df.rename() तरीका एक फ़ंक्शन ले सकता है, उदाहरण के लिए:

In [11]: df.columns
Out[11]: Index([u'$a', u'$b', u'$c', u'$d', u'$e'], dtype=object)

In [12]: df.rename(columns=lambda x: x[1:], inplace=True)

In [13]: df.columns
Out[13]: Index([u'a', u'b', u'c', u'd', u'e'], dtype=object)

df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})

यदि कॉलम की आपकी नई सूची मौजूदा कॉलम के समान क्रम में है, असाइनमेंट सरल है:

new_cols = ['a', 'b', 'c', 'd', 'e']
df.columns = new_cols
>>> df
   a  b  c  d  e
0  1  1  1  1  1

यदि आपके पास पुराने कॉलम नामों पर नए कॉलम नामों के लिए एक शब्दकोश कुंजीपटल था, तो आप निम्न कार्य कर सकते हैं:

d = {'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}
df.columns = df.columns.map(lambda col: d[col])  # Or `.map(d.get)` as pointed out by @PiRSquared.
>>> df
   a  b  c  d  e
0  1  1  1  1  1

यदि आपके पास कोई सूची या शब्दकोश मैपिंग नहीं है, तो आप सूची समझ के माध्यम से अग्रणी $ प्रतीक को पट्टी कर सकते हैं:

df.columns = [col[1:] if col[0] == '$' else col for col in df]

df.columns = ['a', 'b', 'c', 'd', 'e']

आपके द्वारा प्रदान किए गए क्रम में, आपके द्वारा प्रदान किए गए नामों के साथ मौजूदा नामों को प्रतिस्थापित कर दिया जाएगा।

आप उन्हें इंडेक्स द्वारा भी असाइन कर सकते हैं:

df.columns.values[2] = 'c'    #renames the 2nd column to 'c' (in position #3)






rename