Đổi tên cột cụ thể trong gấu trúc


182

Tôi đã có một khung dữ liệu được gọi data. Làm cách nào để đổi tên tiêu đề một cột duy nhất? Ví dụ gdpđể log(gdp)?

data =
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7

7
Chắc chắn có sự chồng chéo, nhưng tôi không rõ ràng ngay từ "Đổi tên cột trong gấu trúc" rằng bạn có thể chọn ra một yếu tố cột đơn độc để đổi tên. Tất nhiên, khi nhìn lại nó là hiển nhiên, và nếu tôi đã đào sâu hơn có lẽ tôi đã tìm ra điều đó, nhưng tôi nghĩ rằng câu hỏi / câu trả lời này tốt hơn khi chỉ ra điều đó.
jeremiahbuddha

Câu trả lời:


359
data.rename(columns={'gdp':'log(gdp)'}, inplace=True)

Chương renametrình cho thấy nó chấp nhận một lệnh là một tham số columnsvì vậy bạn chỉ cần truyền một lệnh với một mục duy nhất.

Cũng thấy liên quan


3
Điều này mất rất nhiều thời gian trên một khung dữ liệu lớn, vì vậy tôi tin rằng điều này có sao chép toàn bộ khung dữ liệu trong bộ nhớ không?
elgehelge

1
@elgehelge không nên làm, hầu hết các hoạt động của gấu trúc sẽ trả về một bản sao và một số chấp nhận một thông số inplace, nếu nó bỏ qua thông số này thì đây là một lỗi, bạn có thể hẹn giờ với và không có thông số không, cũng thử một cái gì đó như new_df = df.rename(columns={'new_name':'old_name'})và xem nếu điều này nhanh hơn hay không
EdChum

1
@ EdChum Cảm ơn. Loại bỏ thông số inplacegần như tăng gấp đôi thời gian từ 14 giây lên 26 giây. Nhưng 14 giây vẫn còn khá lâu để thay đổi tiêu đề ..
elgehelge

2
Chỉ cần một lưu ý, hãy cẩn thận! nếu cột mục tiêu không tồn tại, (đánh vần sai tên hoặc như vậy) thì điều này sẽ không làm gì mà không có lỗi hoặc cảnh báo.
Amir

1
@Quastiat thật đáng buồn vì tại sao một số ops đơn giản này lại nhanh hơn bằng cách hiểu danh sách. Về cơ bản, trừ khi bạn có một df rất lớn, thì điều đó thực sự không quan trọng trừ khi bạn đổi tên nhiều cột trên một df lớn
EdChum

27

Việc triển khai nhanh hơn nhiều sẽ được sử dụng list-comprehensionnếu bạn cần đổi tên một cột.

df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]

Nếu có nhu cầu đổi tên nhiều cột, hãy sử dụng các biểu thức điều kiện như:

df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]

Hoặc, xây dựng ánh xạ bằng cách sử dụng a dictionaryvà thực hiện thao tác list-comprehensionvới nó getbằng cách đặt giá trị mặc định làm tên cũ:

col_dict = {'gdp': 'log(gdp)', 'cap': 'cap_mod'}   ## key→old name, value→new name

df.columns = [col_dict.get(x, x) for x in df.columns]

Thời gian:

%%timeit
df.rename(columns={'gdp':'log(gdp)'}, inplace=True)
10000 loops, best of 3: 168 µs per loop

%%timeit
df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
10000 loops, best of 3: 58.5 µs per loop

Tôi rất thích sử dụng phương pháp này, nhưng tiếc là nó không hoạt động pd.merge_asof()vì đó là một biểu thức :(.
thdoan

14

Làm cách nào để đổi tên một cột cụ thể trong gấu trúc?

Từ v0.24 +, để đổi tên một (hoặc nhiều) cột cùng một lúc,

Nếu bạn cần đổi tên TẤT CẢ các cột cùng một lúc,

  • DataFrame.set_axis()phương pháp với axis=1. Vượt qua một chuỗi giống như danh sách. Tùy chọn có sẵn để sửa đổi tại chỗ là tốt.

rename với axis=1

df = pd.DataFrame('x', columns=['y', 'gdp', 'cap'], index=range(5))
df

   y gdp cap
0  x   x   x
1  x   x   x
2  x   x   x
3  x   x   x
4  x   x   x

Với 0,21+, giờ đây bạn có thể chỉ định một axistham số với rename:

df.rename({'gdp':'log(gdp)'}, axis=1)
# df.rename({'gdp':'log(gdp)'}, axis='columns')
    
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

(Lưu ý rằng renamekhông phải tại chỗ theo mặc định, vì vậy bạn sẽ cần gán lại kết quả .)

Sự bổ sung này đã được thực hiện để cải thiện tính nhất quán với phần còn lại của API. Đối axissố mới tương tự như columnstham số, họ làm điều tương tự.

df.rename(columns={'gdp': 'log(gdp)'})

   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

rename cũng chấp nhận một cuộc gọi lại được gọi một lần cho mỗi cột.

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

   y  g  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

Đối với kịch bản cụ thể này, bạn sẽ muốn sử dụng

df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)

Index.str.replace

Tương tự như replacephương thức chuỗi trong python, pandas Index và Series (chỉ đối tượng dtype) xác định str.replacephương thức ("vectorized") để thay thế dựa trên chuỗi và regex.

df.columns = df.columns.str.replace('gdp', 'log(gdp)')
df
 
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

Ưu điểm của phương thức này so với các phương thức khác là str.replacehỗ trợ regex (được bật theo mặc định). Xem tài liệu để biết thêm thông tin.


Vượt qua một danh sách set_axisvớiaxis=1

Gọi set_axisvới một danh sách (các) tiêu đề. Danh sách phải có độ dài bằng với kích thước cột / chỉ mục. set_axisthay đổi DataFrame gốc theo mặc định, nhưng bạn có thể chỉ định inplace=Falsetrả về một bản sao đã sửa đổi.

df.set_axis(['cap', 'log(gdp)', 'y'], axis=1, inplace=False)
# df.set_axis(['cap', 'log(gdp)', 'y'], axis='columns', inplace=False)

  cap log(gdp)  y
0   x        x  x
1   x        x  x
2   x        x  x
3   x        x  x
4   x        x  x

Lưu ý: Trong các bản phát hành trong tương lai, inplacesẽ mặc định là True.

Chuỗi phương pháp
Tại sao chọn set_axiskhi chúng ta đã có cách gán cột hiệu quả df.columns = ...? Như được hiển thị bởi Ted Petrou trong [câu trả lời này], ( https://stackoverflow.com/a/46912050/4909087 ) set_axisrất hữu ích khi cố gắng xâu chuỗi các phương thức.

Đối chiếu

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

Đấu với

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

Các cựu là cú pháp chảy tự nhiên và tự do hơn.


3

Có ít nhất năm cách khác nhau để đổi tên các cột cụ thể trong gấu trúc và tôi đã liệt kê chúng dưới đây cùng với các liên kết đến câu trả lời ban đầu. Tôi cũng đã định thời gian cho các phương thức này và thấy chúng thực hiện giống nhau (mặc dù YMMV tùy thuộc vào tập dữ liệu và kịch bản của bạn). Trường hợp thử nghiệm dưới đây là đổi tên các cột A M N Zthành A2 M2 N2 Z2trong một khung dữ liệu với các cột Ađể Zchứa một triệu hàng.

# Import required modules
import numpy as np
import pandas as pd
import timeit

# Create sample data
df = pd.DataFrame(np.random.randint(0,9999,size=(1000000, 26)), columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))

# Standard way - https://stackoverflow.com/a/19758398/452587
def method_1():
    df_renamed = df.rename(columns={'A': 'A2', 'M': 'M2', 'N': 'N2', 'Z': 'Z2'})

# Lambda function - https://stackoverflow.com/a/16770353/452587
def method_2():
    df_renamed = df.rename(columns=lambda x: x + '2' if x in ['A', 'M', 'N', 'Z'] else x)

# Mapping function - https://stackoverflow.com/a/19758398/452587
def rename_some(x):
    if x=='A' or x=='M' or x=='N' or x=='Z':
        return x + '2'
    return x
def method_3():
    df_renamed = df.rename(columns=rename_some)

# Dictionary comprehension - https://stackoverflow.com/a/58143182/452587
def method_4():
    df_renamed = df.rename(columns={col: col + '2' for col in df.columns[
        np.asarray([i for i, col in enumerate(df.columns) if 'A' in col or 'M' in col or 'N' in col or 'Z' in col])
    ]})

# Dictionary comprehension - https://stackoverflow.com/a/38101084/452587
def method_5():
    df_renamed = df.rename(columns=dict(zip(df[['A', 'M', 'N', 'Z']], ['A2', 'M2', 'N2', 'Z2'])))

print('Method 1:', timeit.timeit(method_1, number=10))
print('Method 2:', timeit.timeit(method_2, number=10))
print('Method 3:', timeit.timeit(method_3, number=10))
print('Method 4:', timeit.timeit(method_4, number=10))
print('Method 5:', timeit.timeit(method_5, number=10))

Đầu ra:

Method 1: 3.650640267
Method 2: 3.163998427
Method 3: 2.998530871
Method 4: 2.9918436889999995
Method 5: 3.2436501520000007

Sử dụng phương pháp trực quan nhất với bạn và dễ nhất để bạn thực hiện trong ứng dụng của mình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.