Chciałbym połączyć dwa DataFrames i zachować indeks z pierwszej klatki jako indeksu na połączonym zestawie danych. Jednak gdy wykonuję scalanie, wynikowy Dataframe ma indeks całkowcowy. Jak mogę określić, że chcę zachować indeks z lewej ramy danych?

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

Edytuj: Przełączony na przykład kod, który można łatwo odtworzyć

140
DanB 16 sierpień 2012, 00:10

5 odpowiedzi

Najlepsza odpowiedź
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

Uwaga: W przypadku niektórych operacji scalania pozostałych można skończyć z więcej wierszy, jeśli istnieje wiele dopasowań między a i b i będziesz musiał deduplizować (Dokumentacja do deduplikacji). Dlatego pandy nie utrzymuje dla Ciebie indeksu.

181
Acumenus 27 sierpień 2020, 17:58

Możesz wykonać kopię indeksu na lewym dataframe i scal.

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

Znalazłem tę prostą metodę bardzo przydatną podczas pracy z dużym dataframe i przy użyciu pd.merge_asof() (lub dd.merge_asof()).

Takie podejście byłoby lepsze, gdy indeks resetowania jest drogi (duża dataframe).

11
Matthew Son 14 listopad 2019, 18:03

Istnieje rozwiązanie innych niż pd.merge. Korzystanie z map i set_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

I nie wprowadza manekiny index Nazwa indeksu.

8
Acumenus 27 sierpień 2020, 19:32
df1 = df1.merge(
        df2, how="inner", left_index=True, right_index=True
    )

Pozwala to na zachowanie indeksu DF1

7
Acumenus 27 sierpień 2020, 19:34

Myślę, że wymyśliłem inne rozwiązanie. Dołączyłem do lewej tabeli o wartości indeksu i prawej tabeli na wartości kolumny opartej na indeksie lewej tabeli. Co zrobiłem, był normalny scalanie:

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

Następnie pobierałem nowe numery indeksu z scalonego tabeli i umieściłem je w nowej kolumnie o nazwie Numer linii Sentyment:

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

Następnie ręcznie ustawić indeks z powrotem do oryginalnego, lewego wskaźnika tabeli opartego na wcześniej istniejącej kolumnie o nazwie numer linii (wartość kolumnowa, którą dołączyłem z wskaźnika w lewo tabeli):

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

Następnie usunął nazwę indeksu numer linii, aby pozostał pusty:

First10ReviewsJoined.index.name = None

Może trochę haku, ale wydaje się działać dobrze i stosunkowo prosty. Zgadnij również, zmniejsza ryzyko duplikatów / zapamiętania danych. Mam nadzieję, że wszystko ma sens.

0
thedeveloper 24 styczeń 2020, 19:11