Pandalar birleştirmeyi kullanırken dizin nasıl korunur?


126

İkisini birleştirmek istiyorum DataFrames ve ilk çerçevedeki dizini birleştirilmiş veri kümesindeki dizin olarak tutmak . Ancak, birleştirmeyi yaptığımda, sonuçta elde edilen DataFrame tamsayı indeksine sahip. İndeksi sol veri çerçevesinden korumak istediğimi nasıl belirtebilirim?

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

DÜZENLEME: Kolayca yeniden üretilebilen örnek koda geçildi


2
Belirli bir sütunda birleştirirseniz, hangi endekslerin kullanılacağı net değildir (her ikisinin de farklı olması durumunda).
— bonobo

Yanıtlar:


162
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

Not: Bazı sol birleştirme işlemleri için, ave arasında birden fazla eşleşme varsa daha fazla satırla sonuçlanabilir bve tekilleştirmeniz gerekir ( tekilleştirme için belgeler ). Bu yüzden pandalar dizini sizin için tutmuyor.


4
Çok zeki. a.merge (b, nasıl = "sol"). set_index (a.index) de çalışır, ancak daha az sağlam görünür (çünkü ilk bölümü, indeks değerlerini sıfırlamadan önce a'ya kaybeder.)
— DanB

11
Bu özel durum için bunlar eşdeğerdir. Ancak birçok birleştirme işlemi için ortaya çıkan çerçeve, orijinal açerçeveyle aynı sayıda satıra sahip değildir . reset_index, dizini normal bir sütuna taşır ve bu sütundan set_index, birleştirme işlemi nedeniyle a'nın satırları çoğaltıldığında / kaldırıldığında da ilgilenir.
— Wouter Overmeire

1
@Wouter Sol bir birleştirmenin varsayılan olarak neden yeniden dizin oluşturacağını bilmek isterim. Daha fazlasını nereden öğrenebilirim?
— Matthew

7
Güzel! Kullandığım dizin adını açıkça belirtmekten kaçınmak için a.reset_index().merge(b, how="left").set_index(a.index.names).
— Truls

3
Pandalar kötü bir şekilde API'nin tekrar saldıracağını düşündü.
— Henry Henrinson

7

Sol dataframe üzerinde indeksin bir kopyasını oluşturabilir ve birleştirme yapabilirsiniz.

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

Bu basit yöntemi, büyük veri çerçevesiyle çalışırken ve pd.merge_asof()(veyadd.merge_asof() ) .

Bu yaklaşım, indeksi sıfırlamak pahalı olduğunda (büyük veri çerçevesi) daha üstün olacaktır.


1
Bu en iyi cevap. Birleştirme sırasında eski dizinlerinizi korumak istemenizin birçok nedeni vardır (ve kabul edilen yanıt dizinleri korumaz, yalnızca onları sıfırlar). 2'den fazla veri çerçevesini birleştirmeye çalışırken yardımcı olur, vb ...
— Marses

2
(Orijinal) dizin adını koruduğu için üstün çözüm
— Martien Lubberink

olumlu oy verildi, ancak bir uyarıya karşı dikkatli olun, çoklu dizin kullanırken, endeksleriniz [copy_index] adlı tek bir sütunda bir demet olarak saklanacaktır
— geekidharsh

6

Pd.merge olmayan bir çözüm var. kullanılması mapveset_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

Ve indexdizin için sahte bir isim vermez .


1
Çoklu dizinler gibi uç durumlarda muhtemelen daha iyi çalışacağından, bu kabul edilen yanıttan daha üstün görünüyor. Bu konuda yorum yapan var mı?
— BallpointBen

1
soru, ya birden çok sütun atamanız gerekirse, bu yaklaşım işe yarar mı yoksa yalnızca 1 alanla mı sınırlı?
— Yuca

@Yuca: Bu muhtemelen birden çok sütunla çalışmayacaktır, çünkü birden çok sütunu alt kümeye koyduğunuzda, pd.Dataframebir pd.Series. .map()Yöntem, yalnızca tanımlanır pd.Series. Bu şu anlama gelir: a[['to_merge_on_1', 'to_merge_on_2']].map(...)işe yaramaz.
— Dataman

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

Bu, df1 indeksinin korunmasına izin verir


Bu iş gibi görünüyor, ama ben bunu kullandığınızda on=list_of_cols], bu belgelere çelişmektedir: If joining columns on columns, the DataFrame indexes *will be ignored*. Sütunlara karşı indeks kullanmaktan birinin önceliği var mı?
— Itamar Katz

0

Sanırım farklı bir çözüm buldum. Sol tablonun indeksine dayalı bir sütun değeri üzerinde indeks değerinde sol tabloya ve sağ tabloya katılıyordum. Yaptığım şey normal bir birleşmeydi:

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

Sonra birleştirilmiş tablodan yeni dizin numaralarını aldım ve Duygu Satırı Numarası adlı yeni bir sütuna koydum:

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

Ardından dizini, Satır Numarası (sol tablo dizininden katıldığım sütun değeri) olarak adlandırılan önceden var olan sütuna göre orijinal, sol tablo dizinine manuel olarak ayarladım:

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

Ardından, boş kalması için Satır Numarasının dizin adını kaldırın:

First10ReviewsJoined.index.name = None

Belki biraz hack ama iyi ve nispeten basit çalışıyor gibi görünüyor. Ayrıca, verilerinizin kopyalanması / karıştırılması riskini azalttığını tahmin edin. Umarım hepsi mantıklıdır.


0

başka bir basit seçenek, dizini daha önce olduğu gibi yeniden adlandırmaktır:

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

birleştirme, veri çerçevesi 'a'daki sırayı korur, ancak dizini sıfırlar, böylece set_axis kullanmak için kaydedilir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.