ใช้ข้อมูลในเฟรมข้อมูลแพนด้าเพื่อจับคู่คอลัมน์เข้าด้วยกัน


18

ฉันมีสองpandasเฟรมข้อมูลaและ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

และ

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

เฟรมข้อมูลสองเฟรมมีข้อมูลเหมือนกันทุกประการ แต่ในลำดับที่ต่างกันและมีชื่อคอลัมน์ที่ต่างกัน ขึ้นอยู่กับตัวเลขในสองเฟรมข้อมูลที่ฉันต้องการที่จะสามารถให้ตรงกับชื่อคอลัมน์ในแต่ละที่จะชื่อคอลัมน์ในแต่ละab

มันไม่ได้เป็นเรื่องง่ายเหมือนเพียงแค่เปรียบเทียบแถวแรกของaกับแถวแรกของbที่มีค่าซ้ำเช่นทั้งสองa4และa7มีค่า5ดังนั้นจึงเป็นไปไม่ได้ที่จะได้ทันทีตรงกับพวกเขาอย่างใดอย่างหนึ่งหรือb2b4

วิธีที่ดีที่สุดในการทำเช่นนี้คืออะไร?

คำตอบ:


16

นี่คือวิธีใช้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'}

ขอบคุณสำหรับการแบ่งปันคำสั่งที่ดี Anky คุณช่วยอธิบายเพิ่มเติมหน่อยได้[*df1.index]ไหม? จะขอบคุณคุณไชโย
RavinderSingh13

1
@ RavinderSingh13 แน่นอนว่าsort_values(by=..)รับรายการเป็นพารามิเตอร์ดังนั้นฉันเอาออกดัชนีในรายการที่นี่คุณยังสามารถทำlist(df1.index)แทน[*df1.index]:)
Anky

16

นี่เป็นวิธีหนึ่งที่ใช้ประโยชน์จากผู้ใช้จำนวนมาก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'}

อีกวิธีที่คล้ายกัน (โดย @piR):

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
ฉันติดจมูกของคุณในโพสต์ของคุณ หวังว่าคุณจะไม่รังเกียจ กรุณาเปลี่ยนมันตามความต้องการของคุณ
piRSquared

Ah ตรงกันข้าม :) วิธีการที่ดีและการตรวจสอบข้อมูลขนาดใหญ่มันช่วยเพิ่มประสิทธิภาพเล็กน้อย @piRSquared
yatu

12

ทางเดียวของ 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'}

ฉันคิดว่าฉันจะเพิ่มวิธีแก้ปัญหาที่ชาญฉลาดอื่น ๆ เพื่อดูว่ามันเป็นเช่นเดียวกับคุณ (-:
อ๊ะ

8

ความเข้าใจในพจนานุกรม

ใช้tupleค่าคอลัมน์เป็นคีย์ hashable ในพจนานุกรม

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

ในกรณีที่เราไม่มีการนำเสนอที่สมบูรณ์แบบฉันได้สร้างพจนานุกรมสำหรับคอลัมน์ที่มีการแข่งขันเท่านั้น

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

พรมแดนนี้ไร้สาระ ... อย่าทำอย่างนี้จริง

{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
เป็นอย่างไรฉันสามารถเข้าใจแต่ละนิพจน์ในข้อความเหล่านี้ แต่ยังไม่เห็นในหัวของฉันว่าเกิดอะไรขึ้นที่นี่จริง ๆ ? อย่างหมากรุกฉันรู้ว่าจะขยับชิ้นส่วนทั้งหมดบนกระดาน แต่ไม่สามารถมองเห็นสิ่งที่เพิ่มขึ้นได้อีก 2 อย่าง
Scott Boston

โอเค ... ตอนนี้ข้าได้ย่อยแล้วและมันก็ยอดเยี่ยมจริงๆ +1
สกอตต์บอสตัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.