การเปลี่ยนชื่อคอลัมน์ในนุ่น


1823

ฉันมี DataFrame โดยใช้ pandas และเลเบลคอลัมน์ที่ฉันต้องการแก้ไขเพื่อแทนที่เลเบลคอลัมน์เดิม

ฉันต้องการเปลี่ยนชื่อคอลัมน์ใน DataFrame Aโดยที่ชื่อคอลัมน์เดิมคือ:

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

ถึง

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

ฉันมีชื่อคอลัมน์ที่ถูกแก้ไขเก็บไว้ในรายการ แต่ฉันไม่ทราบวิธีการแทนที่ชื่อคอลัมน์


1
คุณอาจต้องการตรวจสอบเอกสารอย่างเป็นทางการที่ครอบคลุมการเปลี่ยนชื่อคอลัมน์: pandas.pydata.org/pandas-docs/stable/user_guide/text.html
ccpizza

คำตอบ:


1828

เพียงกำหนดให้.columnsแอตทริบิวต์:

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

303
เป็นไปได้ไหมที่จะเปลี่ยนชื่อส่วนหัวคอลัมน์เดียว?
ericmjl

112
@ericmjl: สมมติว่าคุณต้องการเปลี่ยนชื่อของตัวแปรแรกของ df จากนั้นคุณสามารถทำสิ่งที่ชอบ:new_columns = df.columns.values; new_columns[0] = 'XX'; df.columns = new_columns
cd98

54
ดูเหมือนว่าคุณจะทำเสร็จแล้ว df.columns.values ​​[0] = 'XX'
RAY

25
เพียงล้อเล่น @RAY - อย่าทำอย่างนั้น ดูเหมือนว่าเป็นรายการที่สร้างขึ้นโดยอิสระจากการจัดทำดัชนีใด ๆ ที่จัดเก็บชื่อคอลัมน์ งานไม่ดีทำลายการตั้งชื่อคอลัมน์ DF ของคุณ ...
มิทช์ลินิน

433
@ericmjl ใช่df.rename(columns = {'$b':'B'}, inplace = True)
nachocab

2845

เปลี่ยนชื่อเฉพาะคอลัมน์

ใช้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 = pd.DataFrame('x', index=range(3), columns=list('abcde'))
df

   a  b  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

วิธีการต่อไปนี้ทำงานและสร้างผลลัพธ์เดียวกัน:

df2 = df.rename({'a': 'X', 'b': 'Y'}, axis=1)  # new method
df2 = df.rename({'a': 'X', 'b': 'Y'}, axis='columns')
df2 = df.rename(columns={'a': 'X', 'b': 'Y'})  # old method  

df2

   X  Y  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

อย่าลืมกำหนดผลลัพธ์กลับมาเนื่องจากการแก้ไขไม่ได้อยู่ในตำแหน่ง อีกทางหนึ่งระบุinplace=True:

df.rename({'a': 'X', 'b': 'Y'}, axis=1, inplace=True)
df

   X  Y  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

จาก v0.25 คุณสามารถระบุerrors='raise'ให้เพิ่มข้อผิดพลาดได้หากระบุการเปลี่ยนชื่อคอลัมน์เป็นชื่อที่ไม่ถูกต้อง ดูv0.25rename()เอกสาร


หัวคอลัมน์ใหม่

ใช้df.set_axis()กับaxis=1และinplace=False(เพื่อส่งคืนสำเนา)

df2 = df.set_axis(['V', 'W', 'X', 'Y', 'Z'], axis=1, inplace=False)
df2

   V  W  X  Y  Z
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

สิ่งนี้ส่งคืนสำเนา แต่คุณสามารถแก้ไข DataFrame แบบแทนที่ได้โดยการตั้งค่าinplace=True(นี่เป็นพฤติกรรมเริ่มต้นสำหรับรุ่น <= 0.24 แต่มีแนวโน้มที่จะเปลี่ยนแปลงในอนาคต)

คุณยังสามารถกำหนดส่วนหัวโดยตรง:

df.columns = ['V', 'W', 'X', 'Y', 'Z']
df

   V  W  X  Y  Z
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

2
เมื่อผมทำเช่นนี้กับกรอบข้อมูล 6 คอลัมน์ (dataframe <กด enter>) เป็นตัวแทนย่อ: code<คลาส 'pandas.core.frame.DataFrame'> Int64Index: 1000 รายการ, 0-999 คอลัมน์ข้อมูล: BodyMarkdown 1000 null ไม่ใช่codeงาน แต่เมื่อฉันทำ dataframe.head () ชื่อเก่าสำหรับคอลัมน์จะปรากฏขึ้นอีกครั้ง
darKoram

12
ฉันกลัวSettingWithCopyWarning:เมื่อฉันใช้ข้อมูลโค้ดที่สองในคำตอบนี้
Monica Heddneck

มีรุ่นนี้แทนที่ regex หรือไม่
denfromufa

@lexual จะเกิดอะไรขึ้นถ้าสองคอลัมน์ที่มีอยู่มีชื่อเหมือนกัน ฉันจะอ้างถึงชื่อคอลัมน์เก่าได้อย่างไร
vagabond

14
ทางออกแรก: df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})เปลี่ยนชื่อที่แสดง แต่ไม่ใช่องค์ประกอบในโครงสร้างข้อมูลพื้นฐาน ดังนั้นถ้าคุณลองdf['newName1']คุณจะได้รับข้อผิดพลาด inplace=Trueเป็นสิ่งที่จำเป็นเพื่อหลีกเลี่ยงการ gotchya ว่า
irritable_phd_syndrom

402

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)

56
ดี สิ่งนี้ช่วยวันของฉัน:df.rename(columns=lambda x: x.lstrip(), inplace=True)
11

2
คล้ายกับ @ root-11 - ในกรณีของฉันมีอักขระที่เป็นสัญลักษณ์แสดงหัวข้อย่อยที่ไม่ได้พิมพ์ในเอาต์พุตคอนโซล IPython ดังนั้นฉันต้องลบมากกว่าช่องว่าง (แถบ) ดังนั้น:t.columns = t.columns.str.replace(r'[^\x00-\x7F]+','')
Red Pea

9
df.rename(columns=lambda x: x.replace(' ', '_'), inplace=True)เป็นอัญมณีเพื่อให้เราสามารถเขียนแทนการเขียนdf.Column_1_Name df.loc[:, 'Column 1 Name']
ตาราง Bobby เล็ก ๆ น้อย ๆ


163

Pandas 0.21+ คำตอบ

มีการอัปเดตที่สำคัญบางอย่างสำหรับการเปลี่ยนชื่อคอลัมน์ในเวอร์ชัน 0.21

  • renameวิธีการได้เพิ่มaxisพารามิเตอร์ซึ่งอาจจะกำหนดให้หรือcolumns 1อัปเดตนี้ทำให้วิธีนี้ตรงกับส่วนที่เหลือของ pandas API มันยังคงมีindexและcolumnsพารามิเตอร์ แต่คุณไม่ได้ถูกบังคับให้ใช้อีกต่อไป
  • set_axisวิธีการที่มีinplaceการตั้งค่าที่จะ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'})

renameฟังก์ชั่นยังยอมรับฟังก์ชั่นที่จะนำไปใช้กับชื่อแต่ละคอลัมน์

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

หรือ

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

ใช้set_axisกับรายการและinplace=False

คุณสามารถระบุรายการให้กับ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คือสามารถใช้เป็นส่วนหนึ่งของห่วงโซ่วิธีการและส่งคืนสำเนาใหม่ของ 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
ขอบคุณสำหรับPandas 0.21+ answer- ฉันคิดถึงส่วนนั้นในส่วน "มีอะไรใหม่" ...
MaxU

1
วิธีแก้ปัญหาดูเหมือนจะใช้ไม่ได้กับ Pandas 3.6: df.rename ({'$ a': 'a', '$ b': 'b', '$ c': 'c', '$ d': 'd ',' $ e ':' e '}, แกน =' คอลัมน์ ') รับอาร์กิวเมนต์คำหลักที่ไม่คาดคิด "แกน"
Arthur D. Howland

3
df.columns = ['a', 'b', 'c', 'd', 'e'] ดูเหมือนว่าจะไม่ทำงานอีกต่อไปทำงานกับเวอร์ชัน 0.22 ฉันมีคำเตือนว่าPandas ไม่อนุญาตให้สร้างคอลัมน์ผ่าน ชื่อแอตทริบิวต์ใหม่ จะเปลี่ยนชื่อได้อย่างไรถ้าคอลัมน์ทั้งหมดของฉันถูกเรียกว่าเหมือนกัน: /
Nabla

มีวิธีการเปลี่ยนชื่อคอลัมน์หนึ่งคอลัมน์หลายคอลัมน์หรือทั้งหมดถ้าคุณไม่ทราบชื่อของคอลัมน์ล่วงหน้า แต่เป็นเพียงดัชนีของพวกเขา ขอบคุณ!
tommy.carstensen

นี่เป็นความคิดเห็นที่มีประโยชน์มาก ตัวอย่างเช่นฟังก์ชั่นแลมบ์ดาตอบคำถามของฉันเกี่ยวกับวิธีการทำดังต่อไปนี้:(df .groupby(['page',pd.Grouper(key='date',freq='MS')])['clicks'].sum() .unstack(1) .rename(lambda x: x.strftime("%Y-%m"), axis='columns') )
วัด

131

เนื่องจากคุณต้องการลบเครื่องหมาย $ ในชื่อคอลัมน์ทั้งหมดคุณสามารถทำได้:

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

หรือ

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

1
อันนี้ไม่เพียง แต่ช่วยในกรณีของ OP แต่ยังอยู่ในข้อกำหนดทั่วไป เช่น: เพื่อแยกชื่อคอลัมน์โดยตัวคั่นและใช้ส่วนหนึ่งของมัน
Deepak


61
old_names = ['$a', '$b', '$c', '$d', '$e'] 
new_names = ['a', 'b', 'c', 'd', 'e']
df.rename(columns=dict(zip(old_names, new_names)), inplace=True)

วิธีนี้คุณสามารถแก้ไขด้วยตนเองnew_namesตามที่คุณต้องการ ใช้งานได้ดีเมื่อคุณต้องการเปลี่ยนชื่อเพียงไม่กี่คอลัมน์เพื่อแก้ไขการสะกดผิดเน้นเสียงลบอักขระพิเศษ ฯลฯ


1
ฉันชอบวิธีนี้ แต่ฉันคิดว่าdf.columns = ['a', 'b', 'c', 'd', 'e']ง่ายกว่า
Christopher Pearson

1
ฉันชอบวิธีการซิปชื่อเก่าและใหม่นี้ เราสามารถใช้df.columns.valuesเพื่อรับชื่อเก่า
bkowshik

1
ฉันแสดงมุมมองแบบตารางและคัดลอกคอลัมน์ไปยัง old_names ฉันคัดลอกอาร์เรย์ข้อกำหนดไปยัง new_name จากนั้นใช้ dict (zip (old_names, new_names)) โซลูชันที่หรูหรามาก
mythicalcoder

ฉันมักจะใช้ชุดย่อยของรายการจากสิ่งที่ชอบ: myList = list(df) myList[10:20], ฯลฯ - ดังนั้นจึงสมบูรณ์แบบ
ทิม Gottgetreu

ที่ดีที่สุดที่จะใช้ชื่อเดิมเป็น @bkowshik ปัญหาแล้วแก้ไขพวกเขาและใส่กลับเข้าไปใหม่พวกเขาคือตามด้วยการแก้ไขบางส่วนแล้วnamez = df.columns.values df.columns = namez
pauljohn32

34

โซลูชันบรรทัดเดียวหรือท่อส่ง

ฉันจะเน้นสองสิ่ง:

  1. OP ระบุอย่างชัดเจน

    ฉันมีชื่อคอลัมน์ที่ถูกแก้ไขเก็บไว้ในรายการ แต่ฉันไม่ทราบวิธีการแทนที่ชื่อคอลัมน์

    ฉันไม่ต้องการแก้ปัญหาวิธีแทนที่'$'หรือถอดอักขระตัวแรกออกจากส่วนหัวของคอลัมน์แต่ละคอลัมน์ OP ทำขั้นตอนนี้แล้ว แต่ฉันต้องการที่จะมุ่งเน้นไปที่การแทนที่columnsวัตถุที่มีอยู่ด้วยใหม่ให้กับรายการของชื่อคอลัมน์ทดแทน

  2. df.columns = newโดยที่newรายการของชื่อคอลัมน์ใหม่นั้นง่ายเท่าที่จะได้รับ ข้อเสียเปรียบของวิธีนี้คือมันต้องมีการแก้ไขcolumnsแอตทริบิวต์ของ dataframe ที่มีอยู่และไม่ได้ทำแบบอินไลน์ ฉันจะแสดงสองสามวิธีในการดำเนินการผ่าน pipelining โดยไม่ต้องแก้ไข dataframe ที่มีอยู่


การติดตั้ง 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คุณมีการทำแผนที่พจนานุกรมชื่อคอลัมน์เก่าชื่อคอลัมน์ใหม่ที่คุณสามารถใช้

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.concatdf

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

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 ช่วยให้เราสามารถตั้งค่าแบบอินไลน์ดัชนี แต่ไม่มีที่สอดคล้องกัน ดังนั้นเราสามารถเปลี่ยนจากนั้นและเปลี่ยนกลับ อย่างไรก็ตามข้อแม้เดียวเปรียบเทียบกับคำเตือนแบบผสมจากโซลูชัน 3 ใช้ที่นี่set_indexpd.DataFrame.set_indexset_columnsset_indexdtypedtype

เดียว 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
ในโซลูชันนี้เราส่งแลมบ์ดาที่ใช้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(lambda x : x.lstrip('$'),axis=1)
YOBEN_S

สวัสดี @piRSquared คุณจะสามารถอธิบายเพิ่มเติมเกี่ยวกับวิธีที่แพนด้าใช้ฟังก์ชัน lambda ในโซลูชัน 5 ได้ไหม ฉันไม่ได้ติดตามสิ่งที่คุณหมายถึงเมื่อคุณพูดว่าxไม่สนใจ
Josmoor98

33

ชื่อคอลัมน์เทียบกับชื่อชุด

ฉันอยากจะอธิบายสิ่งที่เกิดขึ้นเบื้องหลัง

Dataframes เป็นชุดของซีรี่ส์

ซีรี่ส์ในการเปิดเป็นส่วนขยายของ numpy.array

numpy.arrays มีคุณสมบัติ .name

นี่คือชื่อของซีรีส์ เป็นเรื่องที่ไม่ค่อยมีใครนับถือแพนด้านับถือคุณลักษณะนี้ แต่มันอยู่ในสถานที่และสามารถใช้ในการแฮ็คพฤติกรรมของแพนด้า

การตั้งชื่อรายการคอลัมน์

จำนวนมากของคำตอบที่นี่พูดถึงdf.columnsแอตทริบิวต์เป็นเมื่ออยู่ในความเป็นจริงมันเป็นlist Seriesหมายความว่ามี.nameแอตทริบิวต์

นี่คือสิ่งที่เกิดขึ้นหากคุณตัดสินใจที่จะกรอกชื่อคอลัมน์Series:

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แอตทริบิวต์สะท้อนในบางครั้ง ถ้าคุณตั้งค่าdf.columns = ['one', 'two']แล้วจะdf.one.name'one'

หากคุณตั้งค่าdf.one.name = 'three'แล้วdf.columnsจะยังคงให้['one', 'two']และdf.one.nameจะให้'three'

แต่

pd.DataFrame(df.one) จะกลับมา

    three
0       1
1       2
2       3

เพราะหมีแพนด้า reuses ของที่กำหนดไว้แล้ว.nameSeries

ชื่อคอลัมน์หลายระดับ

นุ่นมีวิธีในการทำชื่อคอลัมน์หลายชั้น มีเวทมนตร์ไม่มากที่เกี่ยวข้อง แต่ฉันต้องการที่จะครอบคลุมในคำตอบของฉันเช่นกันเพราะฉันไม่เห็นใครรับที่นี่

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

สามารถทำได้โดยการตั้งค่าคอลัมน์เป็นรายการเช่นนี้

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

18

หากคุณมีชื่อดาต้าคอลัมน์แล้ว 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 วิธี - ใช่

วิธีที่ดีกว่าในการประเมินเทคนิคหลักทั้งหมดที่นำมาตอบคำถามนี้อยู่ด้านล่างโดยใช้ cProfile เพื่อประกันหน่วยความจำและเวลาดำเนินการ @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)')

ทำไมคุณต้องเปลี่ยนวิธี บางสิ่งเช่นนี้ใช้ได้กับฉัน # df.columns = [row.replace ('$', '') สำหรับแถวใน df.columns]
shantanuo

ฉันไม่เข้าใจส่วน 'สิ่งของ' ฉันต้องเปลี่ยนอะไร คอลัมน์เก่า
Andrea Ianni ௫

18

สมมุติว่านี่คือ dataframe ของคุณ

ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถเปลี่ยนชื่อคอลัมน์โดยใช้สองวิธี

  1. การใช้ dataframe.columns=[#list]

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

    ป้อนคำอธิบายรูปภาพที่นี่

    ข้อ จำกัด ของวิธีนี้คือถ้าต้องเปลี่ยนหนึ่งคอลัมน์รายการคอลัมน์แบบเต็มจะต้องถูกส่งผ่าน นอกจากนี้วิธีนี้ไม่สามารถใช้ได้กับป้ายกำกับดัชนี ตัวอย่างเช่นหากคุณผ่านสิ่งนี้:

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

    นี่จะทำให้เกิดข้อผิดพลาด ความยาวไม่ตรงกัน: แกนที่คาดหวังมี 5 องค์ประกอบค่าใหม่มี 4 องค์ประกอบ

  2. อีกวิธีหนึ่งคือวิธี Pandas rename()ซึ่งใช้ในการเปลี่ยนชื่อดัชนีคอลัมน์หรือแถวใด ๆ

    df = df.rename(columns={'$a':'a'})

    ป้อนคำอธิบายรูปภาพที่นี่

ในทำนองเดียวกันคุณสามารถเปลี่ยนแถวหรือคอลัมน์ใด ๆ


17
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]

2
แทนที่จะเป็นlambda col: d[col]คุณจะผ่านd.get... ดังนั้นมันจึงดูเหมือนdf.columns.map(d.get)
piRSquared


15

มาทำความเข้าใจกับการเปลี่ยนชื่อด้วยตัวอย่างเล็ก ๆ ...

1. การเปลี่ยนชื่อคอลัมน์โดยใช้การจับคู่:

df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}) #creating a df with column name A and B
df.rename({"A": "new_a", "B": "new_b"},axis='columns',inplace =True) #renaming column A with 'new_a' and B with 'new_b'

output:
   new_a  new_b
0  1       4
1  2       5
2  3       6

2. การเปลี่ยนชื่อดัชนี / Row_Name โดยใช้การจับคู่:

df.rename({0: "x", 1: "y", 2: "z"},axis='index',inplace =True) #Row name are getting replaced by 'x','y','z'.

output:
       new_a  new_b
    x  1       4
    y  2       5
    z  3       6

คำตอบที่ได้รับการโหวตสูงที่สุดมีตัวอย่างอยู่แล้ว ...
Itamar Mushkin

14

อีกวิธีหนึ่งที่เราสามารถแทนที่ป้ายกำกับคอลัมน์เดิมได้โดยการลอกอักขระที่ไม่ต้องการ (ที่นี่ '$') ออกจากป้ายกำกับคอลัมน์เดิม

สิ่งนี้สามารถทำได้โดยการเรียกใช้สำหรับวนรอบ df.columns และต่อท้ายคอลัมน์ที่ถูกปล้นไปยัง df.columns

แต่เราสามารถทำสิ่งนี้ได้อย่างเรียบร้อยในประโยคเดียวโดยใช้ list comprehension ดังด้านล่าง:

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

( stripวิธีการในงูหลามแถบตัวละครที่กำหนดจากจุดเริ่มต้นและจุดสิ้นสุดของสตริง)


2
คุณช่วยอธิบายได้ว่าทำไมมันถึงได้ผล? นั่นจะทำให้คำตอบมีค่ามากขึ้นสำหรับผู้อ่านในอนาคต
Dan Lowe

12

ง่าย ๆ เพียงแค่ใช้ของจริง

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

และมันจะกำหนดชื่อคอลัมน์ตามลำดับที่คุณวางไว้


10

คุณสามารถใช้str.sliceสำหรับ:

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

1
PS: นี่คือ verbose ที่เทียบเท่ากับdf.columns.str[1:]... น่าจะดีกว่าที่จะใช้มันสั้นกว่าและชัดเจนยิ่งขึ้น
cs95

9

ฉันรู้ว่าคำถามและคำตอบนี้ถูกเคี้ยวจนตาย แต่ฉันอ้างถึงมันเพื่อเป็นแรงบันดาลใจสำหรับหนึ่งในปัญหาที่ฉันมี ฉันสามารถแก้ปัญหาโดยใช้บิตและชิ้นส่วนจากคำตอบที่แตกต่างกันดังนั้นให้การตอบสนองของฉันในกรณีที่ทุกคนต้องการมัน

วิธีการของฉันเป็นเรื่องธรรมดาที่คุณสามารถเพิ่มตัวคั่นเพิ่มเติมโดยคั่นด้วยเครื่องหมายจุลภาค delimiters=และหลักฐานในอนาคต

รหัสการทำงาน:

import pandas as pd
import re


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

delimiters = '$'
matchPattern = '|'.join(map(re.escape, delimiters))
df.columns = [re.split(matchPattern, i)[1] for i in df.columns ]

เอาท์พุท:

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

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

8

โปรดทราบว่าวิธีการเหล่านี้ใช้ไม่ได้กับ MultiIndex สำหรับ MultiIndex คุณต้องทำสิ่งต่อไปนี้:

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

8

ตัวเลือกอื่นคือเปลี่ยนชื่อโดยใช้นิพจน์ทั่วไป:

import pandas as pd
import re

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

df = df.rename(columns=lambda x: re.sub('\$','',x))
>>> df
   a  b  c
0  1  3  5
1  2  4  6

6

หากคุณต้องจัดการกับคอลัมน์จำนวนมากที่ตั้งชื่อโดยระบบการให้บริการที่อยู่นอกเหนือการควบคุมของคุณฉันมาพร้อมกับวิธีการต่อไปนี้ซึ่งเป็นการรวมกันของวิธีการทั่วไปและการแทนที่เฉพาะในคราวเดียว

ขั้นแรกสร้างพจนานุกรมจากชื่อคอลัมน์ dataframe โดยใช้นิพจน์ regex เพื่อทิ้งภาคผนวกบางส่วนของชื่อคอลัมน์แล้วเพิ่มการแทนที่เฉพาะลงในพจนานุกรมเพื่อตั้งชื่อคอลัมน์หลักตามที่คาดไว้ในฐานข้อมูลการรับ

สิ่งนี้จะถูกนำไปใช้กับ dataframe ในครั้งเดียว

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)

5

นอกเหนือจากโซลูชันที่ให้ไว้แล้วคุณสามารถแทนที่คอลัมน์ทั้งหมดในขณะที่คุณกำลังอ่านไฟล์ เราสามารถใช้namesและheader=0เพื่อทำสิ่งนั้น

อันดับแรกเราสร้างรายการชื่อที่เราต้องการใช้เป็นชื่อคอลัมน์ของเรา:

import pandas as pd

ufo_cols = ['city', 'color reported', 'shape reported', 'state', 'time']
ufo.columns = ufo_cols

ufo = pd.read_csv('link to the file you are using', names = ufo_cols, header = 0)

ในกรณีนี้ชื่อคอลัมน์ทั้งหมดจะถูกแทนที่ด้วยชื่อที่คุณมีในรายการของคุณ


4

นี่เป็นฟังก์ชั่นเล็ก ๆ น้อย ๆ ที่ฉันชอบใช้เพื่อลดการพิมพ์:

def rename(data, oldnames, newname): 
    if type(oldnames) == str: #input can be a string or list of strings 
        oldnames = [oldnames] #when renaming multiple columns 
        newname = [newname] #make sure you pass the corresponding list of new names
    i = 0 
    for name in oldnames:
        oldvar = [c for c in data.columns if name in c]
        if len(oldvar) == 0: 
            raise ValueError("Sorry, couldn't find that column in the dataset")
        if len(oldvar) > 1: #doesn't have to be an exact match 
            print("Found multiple columns that matched " + str(name) + " :")
            for c in oldvar:
                print(str(oldvar.index(c)) + ": " + str(c))
            ind = input('please enter the index of the column you would like to rename: ')
            oldvar = oldvar[int(ind)]
        if len(oldvar) == 1:
            oldvar = oldvar[0]
        data = data.rename(columns = {oldvar : newname[i]})
        i += 1 
    return data   

นี่คือตัวอย่างของการทำงาน:

In [2]: df = pd.DataFrame(np.random.randint(0,10,size=(10, 4)), columns=['col1','col2','omg','idk'])
#first list = existing variables
#second list = new names for those variables
In [3]: df = rename(df, ['col','omg'],['first','ohmy']) 
Found multiple columns that matched col :
0: col1
1: col2

please enter the index of the column you would like to rename: 0

In [4]: df.columns
Out[5]: Index(['first', 'col2', 'ohmy', 'idk'], dtype='object')

1
กรณีใช้งานสำหรับฟังก์ชั่นเช่นนี้หายากมาก ในกรณีส่วนใหญ่ฉันรู้ว่าสิ่งที่ฉันกำลังมองหาและสิ่งที่ฉันต้องการที่จะเปลี่ยนชื่อเป็นฉันเพิ่งจะกำหนด / แก้ไขด้วยตนเอง
cs95

1
@ cs95 ฉันมักจะทำงานกับแบบสำรวจระดับชาติหรือนานาชาติขนาดใหญ่ซึ่งตัวแปรจะมีชื่อตัวแปรที่ขึ้นต้นด้วยคำนำหน้าโดยขึ้นอยู่กับตัวเลือกคำตอบ likert scale และการแตกแขนง (เช่น EDU_2913.443, EDU_2913.421, ... ) ฟังก์ชั่นนี้มีประโยชน์มากสำหรับฉันในการทำงานกับชุดประเภทเหล่านั้นฉันเข้าใจว่ามันไม่เหมาะกับคุณ :) :)
seeiespi

3

การเปลี่ยนชื่อคอลัมน์ในนุ่นเป็นเรื่องง่าย

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

2

สมมติว่าคุณสามารถใช้การแสดงออกปกติ วิธีการแก้ปัญหานี้ขจัดความต้องการของการเข้ารหัสด้วยตนเองโดยใช้ regex

import pandas as pd
import re

srch=re.compile(r"\w+")

data=pd.read_csv("CSV_FILE.csv")
cols=data.columns
new_cols=list(map(lambda v:v.group(),(list(map(srch.search,cols)))))
data.columns=new_cols

2
เป็นแนวปฏิบัติที่ดีเกี่ยวกับ Stack Overflow เพื่อเพิ่มคำอธิบายว่าทำไมโซลูชันของคุณจึงทำงานได้ดีกว่าโซลูชันที่มีอยู่ สำหรับข้อมูลเพิ่มเติมอ่านวิธีการตอบ
ซามูเอล Liew

ขอให้สังเกตว่าคำตอบที่ได้รับคะแนนสูงสุดต้องใช้รูปแบบของการเข้ารหัสแบบยากและคำตอบที่ได้คะแนนต่ำที่สุดนั้นต้องการเพียงวิธีการอธิบายและขั้นตอนเท่านั้น?
Kaustubh J

มีโซลูชันที่ดีกว่า (อ่านได้มากขึ้น) ที่ใช้ regex มากกว่านี้ สิ่งนี้กำลังทำมากกว่าที่ควรสำหรับการเปลี่ยนชื่อแบบง่าย นอกจากนี้ยังมีอันตรายจากรูปแบบที่ไม่ตรงกับสิ่งใดซึ่งในกรณีนี้คุณไม่ได้ทำสิ่งใดเพื่อจัดการกับข้อผิดพลาด
cs95
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.