パンダのデータフレームのデータを使用して列を一致させる


18

2つの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

2つのデータフレームにはまったく同じデータが含まれていますが、順序と列名が異なります。2つのデータフレームの番号に基づいて、の各列名をの各列名と照合できるようにしたいと思いaますb

これは単にの最初の行と比較するように簡単にはないaの最初の行とのb重複値があるように、例えば、両方a4a7値を持つ5ことが直ちにいずれかにそれらを一致させることができないようにb2、またはb4

これを行う最良の方法は何ですか?

回答:


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を活用する方法の1つを次に示し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辞書のハッシュ可能キーとして列値の1つを使用します

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が先に移動するのがわかりません。
スコットボストン

わかりました...私はこれを今消化しました、そしてそれは絶対にまだまだ、素晴らしいです。+1
スコットボストン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.