web-dev-qa-db-ja.com

Pandas別のデータフレーム内の一致する列に基づいて新しいデータフレーム列に入力します

100万のdfを持つメインデータを含むrowsがあります。メインデータには30個のcolumnsもあります。ここで、dfという別の列をcategoryに追加します。 categoryは_df2_のcolumnで、約700個のrowsと、columnsの2つのcolumnsと一致する他の2つのdfを含みます。

_df2_のindexとフレーム間で一致するdfを設定することから始めますが、_df2_のindexの一部はdfに存在しません。

_df2_の残りの列は、_AUTHOR_NAME_およびCATEGORYと呼ばれます。

dfの関連列は_AUTHOR_NAME_と呼ばれます。

dfの_AUTHOR_NAME_の一部は_df2_に存在せず、その逆もあります。

私が望む命令は、indexdfが_df2_のindexと一致し、titledfが_df2_のtitleと一致する場合、categorydfを追加し、それ以外の場合はcategoryにNaNを追加します。

サンプルデータ:

_df2
           AUTHOR_NAME              CATEGORY
Index       
Pub1        author1                 main
Pub2        author1                 main
Pub3        author1                 main
Pub1        author2                 sub
Pub3        author2                 sub
Pub2        author4                 sub


df
            AUTHOR_NAME     ...n amount of other columns        
Index       
Pub1        author1                 
Pub2        author1     
Pub1        author2 
Pub1        author3
Pub2        author4 

expected_result
            AUTHOR_NAME             CATEGORY   ...n amount of other columns
Index
Pub1        author1                 main
Pub2        author1                 main
Pub1        author2                 sub
Pub1        author3                 NaN
Pub2        author4                 sub
_

df2.merge(df,left_index=True,right_index=True,how='left', on=['AUTHOR_NAME'])を使用すると、dfが想定より3倍大きくなります。

だから、おそらくマージはこれについて間違った方法だと思った。私が本当にやろうとしていることは、_df2_をルックアップテーブルとして使用し、特定の条件が満たされているかどうかに応じてtypeの値をdfに返すことです。

_def calculate_category(df2, d):
    category_row = df2[(df2["Index"] == d["Index"]) & (df2["AUTHOR_NAME"] == d["AUTHOR_NAME"])]
    return str(category_row['CATEGORY'].iat[0])

df.apply(lambda d: calculate_category(df2, d), axis=1)
_

ただし、これによりエラーがスローされます。

_IndexError: ('index out of bounds', u'occurred at index 7614')
_
15
user3471881

次のデータフレームdfおよびdf2

df = pd.DataFrame(dict(
        AUTHOR_NAME=list('AAABBCCCCDEEFGG'),
        title=      list('zyxwvutsrqponml')
    ))

df2 = pd.DataFrame(dict(
        AUTHOR_NAME=list('AABCCEGG'),
        title      =list('zwvtrpml'),
        CATEGORY   =list('11223344')
    ))

オプション1
merge

df.merge(df2, how='left')

オプション2
join

cols = ['AUTHOR_NAME', 'title']
df.join(df2.set_index(cols), on=cols)

両方のオプションyield

enter image description here

13
piRSquared

アプローチ1:

代わりに concat を使用し、Index列とAUTHOR_NAME列の両方に存在する重複値を削除できます。その後、メンバーシップのチェックに isin を使用します。

df_concat = pd.concat([df2, df]).reset_index().drop_duplicates(['Index', 'AUTHOR_NAME'])
df_concat.set_index('Index', inplace=True)
df_concat[df_concat.index.isin(df.index)]

Image

注:列Indexは、両方のDF'sのインデックス列として設定されると想定されます。


アプローチ2:

示されているようにインデックス列を正しく設定した後、 join を使用します。

df2.set_index(['Index', 'AUTHOR_NAME'], inplace=True)
df.set_index(['Index', 'AUTHOR_NAME'], inplace=True)

df.join(df2).reset_index()

Image

1
Nickil Maveli

ここの他の回答は、質問に対する非常に優れたエレガントなソリューションを提供しますが、非常にエレガントな方法でこの質問に回答するリソースを見つけました。また、参加/ LEFT、RIGHT、INNER、OUTERの結合を効果的に教える、データフレームのマージ。

Join And Merge Pandas Dataframe

このトピックの後、さらに探求者が彼の例を調べたいと思うと正直に感じます...

0
kiltannen