Giải pháp một dòng hoặc đường ống
Tôi sẽ tập trung vào hai điều:
OP nêu rõ
Tôi có các tên cột đã chỉnh sửa được lưu trong danh sách, nhưng tôi không biết cách thay thế tên cột.
Tôi không muốn giải quyết vấn đề làm thế nào để thay thế '$'
hoặc loại bỏ ký tự đầu tiên khỏi mỗi tiêu đề cột. OP đã thực hiện bước này. Thay vào đó tôi muốn tập trung vào việc thay thế columns
đối tượng hiện tại bằng một đối tượng mới được cung cấp một danh sách các tên cột thay thế.
df.columns = new
trong đó new
danh sách các tên cột mới là đơn giản như nó được. Hạn chế của phương pháp này là nó yêu cầu chỉnh sửa columns
thuộc tính của khung dữ liệu hiện có và nó không được thực hiện nội tuyến. Tôi sẽ chỉ ra một vài cách để thực hiện điều này thông qua đường ống mà không cần chỉnh sửa khung dữ liệu hiện có.
Thiết lập 1
Để tập trung vào nhu cầu đổi tên tên cột thay thế bằng danh sách có sẵn, tôi sẽ tạo một khung dữ liệu mẫu mới df
với tên cột ban đầu và tên cột mới không liên quan.
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
Giải pháp 1
pd.DataFrame.rename
Người ta đã nói rằng nếu bạn có một từ điển ánh xạ các tên cột cũ thành các tên cột mới, bạn có thể sử dụng 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
Tuy nhiên, bạn có thể dễ dàng tạo từ điển đó và đưa nó vào cuộc gọi đến rename
. Điều sau đây lợi dụng thực tế là khi lặp đi lặp lại df
, chúng ta lặp lại qua từng tên cột.
# 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
Điều này hoạt động tuyệt vời nếu tên cột ban đầu của bạn là duy nhất. Nhưng nếu họ không, thì điều này bị phá vỡ.
Thiết lập 2
cột không duy nhất
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
Giải pháp 2
pd.concat
sử dụng keys
đối số
Đầu tiên, hãy chú ý những gì xảy ra khi chúng tôi cố gắng sử dụng giải pháp 1:
df.rename(columns=dict(zip(df, new)))
y765 y765 z432
0 1 3 5
1 2 4 6
Chúng tôi đã không ánh xạ new
danh sách như các tên cột. Chúng tôi đã kết thúc lặp lại y765
. Thay vào đó, chúng ta có thể sử dụng keys
đối số của pd.concat
hàm trong khi lặp qua các cột của df
.
pd.concat([c for _, c in df.items()], axis=1, keys=new)
x098 y765 z432
0 1 3 5
1 2 4 6
Giải pháp 3
Tái thiết. Điều này chỉ nên được sử dụng nếu bạn có một dtype
cột cho tất cả các cột. Mặt khác, bạn sẽ kết thúc với dtype
object
tất cả các cột và chuyển đổi chúng trở lại đòi hỏi nhiều công việc từ điển hơn.
Độc thân dtype
pd.DataFrame(df.values, df.index, new)
x098 y765 z432
0 1 3 5
1 2 4 6
Trộn 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
Giải pháp 4
Đây là một mánh khóe phô trương với transpose
và set_index
. pd.DataFrame.set_index
cho phép chúng ta thiết lập một chỉ mục nội tuyến nhưng không có tương ứng set_columns
. Vì vậy, chúng ta có thể chuyển đổi, sau đó set_index
, và chuyển đổi trở lại. Tuy nhiên, cùng một cảnh báo dtype
so với hỗn hợp dtype
từ giải pháp 3 áp dụng ở đây.
Độc thân dtype
df.T.set_index(np.asarray(new)).T
x098 y765 z432
0 1 3 5
1 2 4 6
Trộn 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
Giải pháp 5
Sử dụng một lambda
trong pd.DataFrame.rename
đó chu kỳ thông qua từng yếu tố của new
Trong giải pháp này, chúng tôi vượt qua một lambda mất x
nhưng sau đó bỏ qua nó. Nó cũng mất một y
nhưng không mong đợi nó. Thay vào đó, một trình vòng lặp được đưa ra như một giá trị mặc định và sau đó tôi có thể sử dụng nó để quay vòng qua một lần mà không cần quan tâm đến giá trị của x
nó là gì.
df.rename(columns=lambda x, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
Và như được chỉ ra cho tôi bởi những người trong trò chuyện sopython , nếu tôi thêm một *
ở giữa x
và y
, tôi có thể bảo vệ y
biến của mình . Mặc dù, trong bối cảnh này, tôi không tin rằng nó cần được bảo vệ. Nó vẫn còn đáng nói.
df.rename(columns=lambda x, *, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6