質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

6218閲覧

pandas同士を前方一致させてマージする方法について

mi2

総合スコア63

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

1クリップ

投稿2020/03/23 06:26

前提・実現したいこと

pandasの2つのデータフレームが、以下の例のように存在しています。

ここで、それぞれの2つのカラム名を閾値をもとに前方一致させ、それらをキーにしてデータをマージしたいと考えております。

インプットのデータフレームの例

df = name, size 犬Aの小さい個体の体長, 15 猫Aの小さい個体の体長, 13 金魚Aの体長, 1 犬Aの大きい個体の体長, 110 猫Aの大きい個体の体長, 100 master_df = name, number_of_types 犬, 700 猫, 500 金魚, 100 :

アウトプットのデータフレームの例

output_df = name, number_of_types 犬, 700, 犬Aの小さい個体の体長, 15 犬, 700, 犬Aの大きい個体の体長, 110 猫, 500, 猫Aの小さい個体の体長, 13 猫, 500, 猫Aの大さい個体の体長, 100 金魚, 100, 金魚Aの体長, 1 :

参考:エクセル上での抽出イメージ

前方一致検索でVLOOKUPを使うと出来ます。
このような内容をpythonで書きたいです。
https://office-hack.com/excel/vlookup-wildcard/

考えたこと

完全一致や部分一致で特定のdfから条件に合うものは、以下のように書けると思います。

df_master['name'] == '犬' df['name'].str.contains('犬', na=False)

上記のような抽出のイメージはあるのですが、2つのpandasのデータフレーム上で検索して前方一致でマージする方法についてお知恵を拝借できましたら幸いです。
何卒よろしくお願い申し上げます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Python

1master_df['name'].apply(lambda n: df['name'].str.startswith(n)).idxmax()

にて対象となるデータフレームの Index値を得ることができるかと思いますので、あとは pandas.merge() すると良いかと思います。

Python

1import pandas as pd 2 3df = pd.DataFrame({ 4 'name' : ['犬Aの小さい個体の体長', '猫Aの小さい個体の体長', 5 '金魚Aの体長', '犬Aの大きい個体の体長', '猫Aの大きい個体の体長'], 6 'size' : [15, 13, 1, 110, 100]}) 7master_df = pd.DataFrame({ 8 'name' : ['犬', '猫', '金魚'], 9 'number_of_types' : [700, 500, 100]}) 10 11df['target'] = master_df['name'].apply(lambda n: df['name'].str.startswith(n)).idxmax() 12 13ret = pd.merge(df, master_df, left_on='target', right_index=True, how='left').drop('target', axis=1) 14# name_x size name_y number_of_types 15#0 犬Aの小さい個体の体長 15 犬 700 16#1 猫Aの小さい個体の体長 13 猫 500 17#2 金魚Aの体長 1 金魚 100 18#3 犬Aの大きい個体の体長 110 犬 700 19#4 猫Aの大きい個体の体長 100 猫 500

投稿2020/03/23 08:32

編集2020/03/23 08:33
magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

dfに別の列を作ってdfのnameにmaster_dfのnameが含まれていたら、
master_dfのnameを登録しておいてそれをキーとして利用する方法はどうでしょう。

python

1import pandas as pd 2 3df = pd.DataFrame( 4 [['犬Aの小さい個体の体長', 15], 5 ['猫Aの小さい個体の体長', 13], 6 ['金魚Aの体長', 1], 7 ['犬Aの大きい個体の体長', 110], 8 ['猫Aの大きい個体の体長', 100]], 9 columns=['name', 'size']) 10 11master_df = pd.DataFrame( 12 [['犬', 700], 13 ['猫', 500], 14 ['金魚', 100]], 15 columns=['name', 'number_of_types']) 16 17#master_dfのname列を繰り返し処理 18for column_name, item in master_df.name.iteritems(): 19 #dfのnameにmaster_dfのnameが含まれる場合、master_dfのnameをdfのname_key列として追加 20 df.loc[df.name.str.contains(item), 'name_key'] = item 21print(df) 22''' 23 name size name_key 240 犬Aの小さい個体の体長 15 犬 251 猫Aの小さい個体の体長 13 猫 262 金魚Aの体長 1 金魚 273 犬Aの大きい個体の体長 110 犬 284 猫Aの大きい個体の体長 100 猫 29''' 30 31#master_dfのname列とdfのname_key列で結合し、name_key列を削除 32output_df = pd.merge(master_df, df, left_on='name', right_on='name_key', how='inner').drop("name_key", axis=1) 33print(output_df) 34''' 35 name_x number_of_types name_y size 360 犬 700 犬Aの小さい個体の体長 15 371 犬 700 犬Aの大きい個体の体長 110 382 猫 500 猫Aの小さい個体の体長 13 393 猫 500 猫Aの大きい個体の体長 100 404 金魚 100 金魚Aの体長 1 41'''

投稿2020/03/23 08:02

編集2020/03/23 08:20
yureighost

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問