Sütunları birlikte eşleştirmek için panda veri çerçevelerindeki verileri kullanma


18

İki pandasveri çerçevem var ave b:

a1   a2   a3   a4   a5   a6   a7
1    3    4    5    3    4    5
0    2    0    3    0    2    1
2    5    6    5    2    1    2

ve

b1   b2   b3   b4   b5   b6   b7
3    5    4    5    1    4    3
0    1    2    3    0    0    2
2    2    1    5    2    6    5

İki veri çerçevesi tam olarak aynı verileri içerir, ancak farklı bir sırada ve farklı sütun adlarıyla. İki veri çerçevelerinde sayılar dayanarak, her sütun adı eşleştirmek mümkün istiyorum aher sütun adının b.

Bu kadar kolay basitçe ilk satırı karşılaştırma yapmadığı ailk satırına ile börneğin her ikisi için, değerleri vardır çoğaltıldığı olarak a4ve a7değere sahip 5derhal ya bunları eşleştirmek mümkün değildir bu yüzden b2ya b4.

Bunu yapmanın en iyi yolu nedir?

Yanıtlar:


16

İşte kullanmanın bir yolu sort_values:

m=df1.T.sort_values(by=[*df1.index]).index
n=df2.T.sort_values(by=[*df2.index]).index
d=dict(zip(m,n))
print(d)

{'a1': 'b5', 'a5': 'b1', 'a2': 'b7', 'a3': 'b6', 'a6': 'b3', 'a7': 'b2', 'a4': 'b4'}

Hoş komut paylaştığın için teşekkür ederim Anky, lütfen biraz daha açıklayabilir [*df1.index]misin? Size minnettar olacağım, şerefe.
RavinderSingh13

1
@ RavinderSingh13 Tabii, sort_values(by=..)bir parametre olarak bir liste alır , bu yüzden indeksi burada bir listeye açmak, list(df1.index)bunun yerine de yapabilirsiniz [*df1.index]:)
anky

16

İşte numpy'yi kullanmanın tek yolu broadcasting:

b_cols = b.columns[(a.values == b.T.values[...,None]).all(1).argmax(1)]
dict(zip(a, b_cols))

{'a1': 'b5',
 'a2': 'b7',
 'a3': 'b6',
 'a4': 'b4',
 'a5': 'b1',
 'a6': 'b3',
 'a7': 'b2'}

Başka bir benzer yaklaşım (@piR tarafından):

a_ = a.to_numpy()
b_ = b.to_numpy()
i, j = np.where((a_[:, None, :] == b_[:, :, None]).all(axis=0))
dict(zip(a.columns[j], b.columns[i]))

{'a1': 'b5',
 'a2': 'b7',
 'a3': 'b6',
 'a4': 'b4',
 'a5': 'b1',
 'a6': 'b3',
 'a7': 'b2'}

1
Burnuma yazıya takıldım. Umarım, aldırmazsın. Lütfen isteğinize göre değiştirin.
piRSquared

Ah tam tersine :) Güzel bir yaklaşım ve büyük veri karelerini kontrol ederek performansı biraz arttırır @piRSquared
yatu

12

Bir yolu merge

s=df1.T.reset_index().merge(df2.T.assign(match=lambda x : x.index))
dict(zip(s['index'],s['match']))
{'a1': 'b5', 'a2': 'b7', 'a3': 'b6', 'a4': 'b4', 'a5': 'b1', 'a6': 'b3', 'a7': 'b2'}

Sadece seninkiyle aynı olduğunu görmek için başka bir akıllı çözüm ekleyeceğimi düşündüm (-:
whoops

8

sözlük anlama

Bir kullan tuplebir sözlükte hashable anahtar olarak sütun değerlerinin

d = {(*t,): c for c, t in df2.items()}
{c: d[(*t,)] for c, t in df1.items()}

{'a1': 'b5',
 'a2': 'b7',
 'a3': 'b6',
 'a4': 'b4',
 'a5': 'b1',
 'a6': 'b3',
 'a7': 'b2'}

Mükemmel temsile sahip olmamamız durumunda, sadece bir eşleşmenin olduğu sütunlar için sözlüğü ürettim.

d2 = {(*t,): c for c, t in df2.items()}
d1 = {(*t,): c for c, t in df1.items()}

{d1[c]: d2[c] for c in {*d1} & {*d2}}

{'a5': 'b1',
 'a2': 'b7',
 'a7': 'b2',
 'a6': 'b3',
 'a3': 'b6',
 'a1': 'b5',
 'a4': 'b4'}

idxmax

Bu saçma sınırlar ... Aslında bunu yapma.

{c: df2.T.eq(df1[c]).sum(1).idxmax() for c in df1}

{'a1': 'b5',
 'a2': 'b7',
 'a3': 'b6',
 'a4': 'b4',
 'a5': 'b1',
 'a6': 'b3',
 'a7': 'b2'}

1
Bu ifadelerdeki her ifadeyi nasıl anlayabilirim, ama kafamda tam olarak ne olduğunu tam olarak göremiyorum? Satranç gibi, tahtadaki tüm parçaları nasıl taşıyacağımı biliyorum, ama 2'den fazla hareket göremiyorum.
Scott Boston

Tamam ... Bunu şimdi sindirdim ve kesinlikle basit, parlak. +1
Scott Boston
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.