Cách giữ chỉ mục khi sử dụng hợp nhất gấu trúc


126

Tôi muốn hợp nhất hai DataFramesvà giữ chỉ mục từ khung đầu tiên làm chỉ mục trên tập dữ liệu đã hợp nhất. Tuy nhiên, khi tôi thực hiện hợp nhất, DataFrame kết quả có chỉ mục số nguyên. Làm cách nào để xác định rằng tôi muốn giữ chỉ mục từ khung dữ liệu bên trái?

In [4]: a = pd.DataFrame({'col1': {'a': 1, 'b': 2, 'c': 3}, 
                          'to_merge_on': {'a': 1, 'b': 3, 'c': 4}})

In [5]: b = pd.DataFrame({'col2': {0: 1, 1: 2, 2: 3}, 
                          'to_merge_on': {0: 1, 1: 3, 2: 5}})

In [6]: a
Out[6]:
   col1  to_merge_on
a     1            1
b     2            3
c     3            4

In [7]: b
Out[7]:
   col2  to_merge_on
0     1            1
1     2            3
2     3            5

In [8]: a.merge(b, how='left')
Out[8]:
   col1  to_merge_on  col2
0     1            1   1.0
1     2            3   2.0
2     3            4   NaN

In [9]: _.index
Out[9]: Int64Index([0, 1, 2], dtype='int64')

CHỈNH SỬA: Được chuyển sang mã ví dụ có thể dễ dàng sao chép


2
nếu bạn hợp nhất trên một cột cụ thể, bạn không rõ sẽ sử dụng chỉ số nào (trong trường hợp cả hai đều khác nhau).
bonobo

Câu trả lời:


161
In [5]: a.reset_index().merge(b, how="left").set_index('index')
Out[5]:
       col1  to_merge_on  col2
index
a         1            1     1
b         2            3     2
c         3            4   NaN

Lưu ý: đối với một số thao tác hợp nhất bên trái, bạn có thể kết thúc với nhiều hàng hơn nếu có nhiều kết quả phù hợp giữa abvà bạn sẽ cần phải loại bỏ trùng lặp ( tài liệu về loại bỏ trùng lặp ). Đây là lý do tại sao gấu trúc không giữ chỉ số cho bạn.


4
Rất thông minh. a.merge (b, how = "left"). set_index (a.index) cũng hoạt động, nhưng nó có vẻ kém mạnh mẽ hơn (vì phần đầu tiên của nó mất các giá trị chỉ mục thành a trước khi đặt lại chúng.)
DanB

11
Đối với trường hợp cụ thể này, chúng là tương đương. Nhưng đối với nhiều hoạt động hợp nhất, khung kết quả không có cùng số hàng với akhung ban đầu . reset_index di chuyển chỉ mục đến một cột thông thường và set_index từ cột này sau khi hợp nhất cũng sẽ cẩn thận khi các hàng của a bị trùng lặp / bị xóa do hoạt động hợp nhất.
Wouter Overmeire,

1
@Wouter Tôi muốn biết lý do tại sao hợp nhất bên trái sẽ lập chỉ mục theo mặc định. Tôi có thể tìm hiểu thêm ở đâu?
Matthew

7
Đẹp! Để tránh chỉ định rõ ràng tên-chỉ mục mà tôi sử dụng a.reset_index().merge(b, how="left").set_index(a.index.names).
Truls

3
Gấu trúc nghĩ xấu API lại xảy ra.
Henry Henrinson

7

Bạn có thể tạo một bản sao chỉ mục trên khung dữ liệu bên trái và thực hiện hợp nhất.

a['copy_index'] = a.index
a.merge(b, how='left')

Tôi thấy phương pháp đơn giản này rất hữu ích khi làm việc với khung dữ liệu lớn và sử dụng pd.merge_asof()(hoặc dd.merge_asof()).

Cách tiếp cận này sẽ tốt hơn khi việc đặt lại chỉ mục là tốn kém (khung dữ liệu lớn).


1
Đây là câu trả lời tốt nhất. Có nhiều lý do tại sao bạn muốn giữ lại các chỉ mục cũ của mình trong khi hợp nhất (và câu trả lời được chấp nhận không bảo toàn các chỉ mục, nó chỉ đặt lại chúng). Nó giúp khi bạn đang cố gắng hợp nhất hơn 2 dataframes, và vân vân ...
Marses

2
Giải pháp vượt trội như nó bảo tên (gốc) index
Martien Lubberink

upvoted nhưng chỉ cần cảnh giác với một caveat, khi sử dụng đa-index, chỉ số của bạn sẽ được lưu trữ như một tuple trong một cột duy nhất gọi là [copy_index]
geekidharsh

6

Có một giải pháp phi pd.merge. Sử dụng mapset_index

In [1744]: a.assign(col2=a['to_merge_on'].map(b.set_index('to_merge_on')['col2']))
Out[1744]:
   col1  to_merge_on  col2
a     1            1   1.0
b     2            3   2.0
c     3            4   NaN

Và, không giới thiệu indextên giả cho chỉ mục.


1
Điều này có vẻ cao hơn câu trả lời được chấp nhận vì nó có thể sẽ hoạt động tốt hơn với các trường hợp cạnh như nhiều chỉ mục. Bất cứ ai có thể bình luận về điều này?
BallpointBen

1
câu hỏi, điều gì sẽ xảy ra nếu bạn cần gán nhiều cột, cách tiếp cận này có hoạt động không hay chỉ giới hạn ở 1 trường?
Yuca

@Yuca: Điều này có thể sẽ không hoạt động với nhiều cột, vì khi bạn đặt con nhiều cột, bạn sẽ kết thúc bằng a pd.Dataframechứ không phải a pd.Series. Các .map()phương pháp duy nhất được định nghĩa cho pd.Series. Điều này có nghĩa là: a[['to_merge_on_1', 'to_merge_on_2']].map(...)sẽ không hoạt động.
Dataman

4
df1 = df1.merge(
        df2, how="inner", left_index=True, right_index=True
    )

Điều này cho phép duy trì chỉ mục của df1


Dường như với công việc, nhưng khi tôi sử dụng nó với on=list_of_cols], nó mâu thuẫn với tài liệu hướng dẫn: If joining columns on columns, the DataFrame indexes *will be ignored*. Việc sử dụng chỉ số so với cột có được ưu tiên không?
Itamar Katz

0

Hãy nghĩ rằng tôi đã nghĩ ra một giải pháp khác. Tôi đã kết hợp bảng bên trái trên giá trị chỉ mục và bảng bên phải trên một giá trị cột dựa trên chỉ mục của bảng bên trái. Những gì tôi đã làm là hợp nhất bình thường:

First10ReviewsJoined = pd.merge(First10Reviews, df, left_index=True, right_on='Line Number')

Sau đó, tôi lấy các số chỉ mục mới từ bảng đã hợp nhất và đặt chúng vào một cột mới có tên Số dòng cảm xúc:

First10ReviewsJoined['Sentiment Line Number']= First10ReviewsJoined.index.tolist()

Sau đó, tôi đặt chỉ mục theo cách thủ công trở lại chỉ mục bảng bên trái, ban đầu dựa trên cột có sẵn từ trước được gọi là Số dòng (giá trị cột mà tôi đã tham gia từ chỉ mục bảng bên trái):

First10ReviewsJoined.set_index('Line Number', inplace=True)

Sau đó, xóa tên chỉ mục của Số dòng để nó vẫn trống:

First10ReviewsJoined.index.name = None

Có thể là một chút hack nhưng dường như hoạt động tốt và tương đối đơn giản. Ngoài ra, đoán nó làm giảm nguy cơ trùng lặp / xáo trộn dữ liệu của bạn. Hy vọng rằng tất cả đều có ý nghĩa.


0

một tùy chọn đơn giản khác là đổi tên chỉ mục thành trước đó:

a.merge(b, how="left").set_axis(a.index)

hợp nhất bảo toàn thứ tự tại khung dữ liệu 'a', nhưng chỉ đặt lại chỉ mục để nó được lưu để sử dụng set_axis

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.