팬더 데이터 프레임의 데이터를 사용하여 열을 일치시킵니다.


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

두 데이터 프레임에는 정확히 동일한 데이터가 포함되지만 순서가 다르고 열 이름이 다릅니다. 두 개의 데이터 프레임의 숫자를 바탕으로, 나는 각 열 이름과 일치 할 수 있도록하고 싶습니다 a의 각 열 이름 b.

그것은 쉽게 단순히의 첫 번째 행을 비교하지 않습니다 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

numpy를 활용하는 한 가지 방법이 있습니다 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

아아 반대로 :) 좋은 접근 방식과 큰 데이터 프레임을 확인하면 @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'}

- 나는 그것이 당신 (같은 것을 볼 만 다른 영리 솔루션을 추가 할 거라고 생각 :. 으악
piRSquared

8

사전 이해

tuple사전에서 해시 키로 열 값 중 하나 를 사용하십시오.

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
Scott Boston
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.