python - يعيش - صفات دب الباندا




إعادة تسمية الأعمدة في الباندا (16)

لدي DataFrame باستخدام تصنيفات الباندا والأعمدة التي أحتاج إلى تعديلها لاستبدال تسميات الأعمدة الأصلية.

أرغب في تغيير أسماء الأعمدة في DataFrame A حيث أسماء الأعمدة الأصلية هي:

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

إلى

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

لدي أسماء الأعمدة المعدلة المخزنة في قائمة ، لكنني لا أعرف كيفية استبدال أسماء الأعمدة.


DataFrame - df.rename () ستعمل.

df.rename(columns = {'Old Name':'New Name'})

df هو DataFrame لديك ، ويكون الاسم القديم هو اسم العمود الذي تريد تغييره ، ثم الاسم الجديد هو الاسم الجديد الذي تقوم بالتغيير إليه. تجعل هذه الطريقة المضمنة في DataFrame الأشياء أكثر سهولة.


Pandas 0.21+ الجواب

كانت هناك بعض التحديثات الهامة لإعادة تسمية العمود في الإصدار 0.21.

  • أضافت طريقة rename axis معلمة axis التي يمكن ضبطها على columns أو 1 . يجعل هذا التحديث هذه الطريقة مطابقة لبقية API pandas. لا يزال يحتوي على معلمات index columns ولكن لم تعد مضطرة لاستخدامها.
  • set_axis الأسلوب set_axis مع inplace set_axis إلى False من إعادة تسمية كل الفهرس أو تصنيفات الأعمدة مع قائمة.

أمثلة ل Pandas 0.21+

بناء نموذج DataFrame:

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

استخدام rename مع axis='columns' أو axis=1

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)

باستخدام set_axis مع قائمة و inplace=False

يمكنك توفير قائمة بطريقة set_axis متساوية الطول لعدد الأعمدة (أو الفهرس). حاليًا ، سيتم تعيين الإعدادات الافتراضية في الوضع الحالي إلى 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 هي أنه يمكن استخدامه كجزء من سلسلة الطريقة وإرجاع نسخة جديدة من DataFrame. بدونه ، سيكون عليك تخزين خطواتك الوسيطة من السلسلة إلى متغير آخر قبل إعادة تعيين الأعمدة.

# 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()

خط واحد أو حلول خطوط الأنابيب

سأركز على شيئين:

  1. البروتوكول الاختياري تنص بوضوح

    لدي أسماء الأعمدة المعدلة المخزنة في قائمة ، لكنني لا أعرف كيفية استبدال أسماء الأعمدة.

    لا أريد حل مشكلة كيفية استبدال '$' أو فصل الحرف الأول من كل رأس عمود. لقد قام OP بالفعل بهذه الخطوة. بدلاً من ذلك ، أريد التركيز على استبدال كائن columns الموجودة columns جديدة ، مع توفير قائمة بأسماء أعمدة الاستبدال.

  2. df.columns = new where new is the list of new columns names is as simple as gets. العيب في هذا النهج هو أنه يتطلب تحرير سمة columns مخطط البيانات الموجودة حاليًا ولا يتم تضمينها في السطر. سأعرض بعض الطرق لتنفيذ ذلك عبر خط الأنابيب دون تحرير مخطط البيانات الحالي.

الإعداد 1
للتركيز على الحاجة إلى إعادة تسمية استبدال أسماء الأعمدة بقائمة موجودة مسبقًا ، سوف أقوم بإنشاء نموذج جديد dataframe 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 أسماء الأعمدة القديمة إلى أسماء أعمدة جديدة ، فيمكنك استخدام 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
pd.concat باستخدام وسيطة keys

أولاً ، لاحظ ما يحدث عندما نحاول استخدام الحل 1:

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

   y765  y765  z432
0     1     3     5
1     2     4     6

لم نقم بتعيين القائمة new كأسماء الأعمدة. لقد انتهى الأمر تكرار y765 . بدلاً من ذلك ، يمكننا استخدام وسيطة keys الخاصة بوظيفة pd.concat أثناء التكرار خلال أعمدة df .

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 واحد لجميع الأعمدة. خلاف ذلك ، سوف ينتهي بك الأمر مع 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 . يسمح لنا pd.DataFrame.set_index بتعيين فهرس مضمّن ، ولكن لا يوجد أي عدد من set_columns المقابلة. حتى نتمكن من تبديل ، ثم set_index ، وإعادة تحويلها. ومع ذلك ، dtype نفس dtype واحد ضد dtype caveat من الحل 3 هنا.

نوع 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
استخدم lambda في pd.DataFrame.rename الذي يمر عبر كل عنصر new
في هذا الحل ، نجتاز lambda يأخذ x ولكنه يتجاهلها. يأخذ أيضا y لكن لا نتوقع ذلك. وبدلاً من ذلك ، يتم إعطاء المكرّر كقيمة افتراضية ، ويمكنني حينئذٍ استخدام ذلك للتنقل خلال وقت واحد دون النظر إلى قيمة x .

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

   x098  y765  z432
0     1     3     5
1     2     4     6

وكما أشار إلي من قبل الناس في دردشة sopython ، إذا أضفت * بين x و y ، يمكنني حماية متغير y . رغم ذلك ، لا أعتقد أنه في هذا السياق يحتاج إلى حماية. لا يزال من الجدير بالذكر.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

أعتقد أن هذه الطريقة مفيدة:

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

تسمح لك هذه الطريقة بتغيير أسماء الأعمدة على حدة.


إذا كان عليك التعامل مع الكثير من الأعمدة التي يطلق عليها نظام التزويد خارج سيطرتك ، فقد توصلت إلى النهج التالي الذي هو مزيج من النهج العام والاستبدال المحدد في دفعة واحدة.

أولاً ، أنشئ قاموسًا من أسماء أعمدة برنامج dataframe باستخدام تعبيرات regex من أجل التخلص من بعض ملحقات أسماء الأعمدة ثم أقوم بإضافة بدائل معينة إلى القاموس لتسمية أعمدة أساسية كما هو متوقع في وقت لاحق في قاعدة بيانات الاستلام.

ثم يتم تطبيق ذلك على مخطط البيانات دفعة واحدة.

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)

إذا كنت قد حصلت على dataframe ، df.columns مقالب كل شيء في قائمة يمكنك التلاعب بها ومن ثم إعادة تعيين في dataframe الخاص بك كأسماء الأعمدة ...

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. طريقة - نعم.

توجد طريقة أفضل لتقييم جميع التقنيات الرئيسية المطروحة في إجابات السؤال أدناه باستخدام cProfile إلى ذاكرة gage ووقت التنفيذ. كانkadee وkaitlyn وeumiro يتمتعون بوظائف ذات أوقات تنفيذ أسرع - على الرغم من أن هذه الوظائف سريعة جدًا ، فنحن نقارن تقريب 1000 و 0،01 ثانية لجميع الإجابات. الأخلاقية: إجابتي فوق الأرجح ليست طريقة "أفضل".

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)')

استخدم الدالة 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(index=str, columns={"$a": "a", "$b": "b", "$c" : "c", "$d" : "d", "$e" : "e"})

في حال كنت لا تريد أسماء الصف df.columns = ['a', 'b',index=False]



ما عليك .columns تعيينها إلى سمة .columns :

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

نظرًا لأنك تريد فقط إزالة علامة $ في جميع أسماء الأعمدة ، فيمكنك إجراء ما يلي:

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

أو

df.rename(columns=lambda x: x.replace('$', ''), 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)

يمكنك استخدام str.slice لذلك:

df.columns = df.columns.str.slice(1)

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