2016-03-18 15 views
3

私はdf1df2という2つのデータフレームを持っています。 df2からDisplay Namedf1Display Name列にある場合、私はdf2の値にdf1TypeFormatBehaviorDatatype値を割り当てます。Pandas:別のデータフレームから重複した行を使用して複数のデータフレーム列を更新

私は考えることができるあらゆる方法でmergeを試しました。私はlocが私の最高の希望だと思っていますが、私は割り当ての構文を正しく得ることができません。また、私は簡潔な答え、好ましくは1つのライナーを探しています。

このような何か:

df2.loc[df2['Display Name'].isin(df1['Display Name']),/
     ['Type', 'Format', 'Behavior', 'Datatype']] = ??? 

マイコード:

import pandas as pd 
import numpy as np 

df1 = pd.DataFrame(
    {'Behavior': ['Attribute', 'Attribute', 'Attribute', 'Attribute', 'Attribute', 
       'Attribute', 'Attribute', 'Metric', 'Metric', 'Metric', 'Metric', 
       'Metric', 'Metric', 'Metric', 'Metric'], 
    'Datatype': ['object', 'object', 'object', 'object', 'object', 'object', 
       'object', 'int64', 'int64', 'int64', 'int64', 'float64', 
       'float64', 'float64', 'float64'], 
    'Display Name': ['Campaign', 'Campaign ID', 'Campaign ID', 'Campaign state', 
        'Campaign state', 'Currency', 'Currency', 'Impressions', 
        'Impressions', 'Clicks', 'Clicks', 'CTR', 'CTR', 'Avg. CPC', 
        'Avg. CPC'], 
    'Format': ['{}', '{}', '{}', '{}', '{}', '{}', '{}', '{:,.0f}', '{:,.0f}', 
      '{:,.0f}', '{:,.0f}', '{:.2f}%', '{:.2f}%', '${:,.2f}', '${:,.2f}'], 
    'Type': ['String', 'String', 'String', 'String', 'String', 'String', 'String', 
      'Integer', 'Integer', 'Integer', 'Integer', 'Percent', 'Percent', 
      'Currency', 'Currency']}, 
    columns=['Display Name', 'Type', 'Format', 'Behavior', 'Datatype']) 

df2 = pd.DataFrame(
    { 'Behavior': [ 'Attribute', 'Metric', 'Metric', 'Metric', 'Attribute', 
       'Metric', 'Metric', 'Attribute', 'Metric', 'Metric', 'Metric'], 
    'Datatype': [ 'object', 'float64', 'float64', 'float64', 'object', 'int64', 
       'int64', 'object', 'float64', 'float64', 'float64'], 
    'Display Name': [ 'Match type', 'Destination URL', 'Final URL', 
        'Mobile final URL', 'Labels', 'Impressions', 'Clicks', 
        'CTR', 'Avg. CPC', 'Cost', 'Avg. position'], 
    'Format': [ '{}', '{:.2f}', '{:.2f}', '{:.2f}', '{}', '{:,.0f}', '{:,.0f}', 
       '{}', '{:.2f}', '{:.2f}', '{:.2f}'], 
    'Type': [ 'String', 'Float', 'Float', 'Float', 'String', 'Integer', 
      'Integer', 'String', 'Float', 'Float', 'Float']}, 
    columns=['Display Name', 'Type', 'Format', 'Behavior', 'Datatype']) 

df2_vals_in_df1 = df2.loc[df2['Display Name'].isin(df1['Display Name']), df2.columns[:]] 
df1_vals_in_df2 = df1.loc[df1['Display Name'].isin(df2['Display Name']), df1.columns[:]] 

それがどのように見える:df1_vals_in_df2Display Nameは、同じ名前を複数回持っているかもしれない方法

>>> df1 
     Display Name  Type Format Behavior Datatype 
0   Campaign String  {} Attribute object 
1  Campaign ID String  {} Attribute object 
2  Campaign ID String  {} Attribute object 
3 Campaign state String  {} Attribute object 
4 Campaign state String  {} Attribute object 
5   Currency String  {} Attribute object 
6   Currency String  {} Attribute object 
7  Impressions Integer {:,.0f}  Metric int64 
8  Impressions Integer {:,.0f}  Metric int64 
9   Clicks Integer {:,.0f}  Metric int64 
10   Clicks Integer {:,.0f}  Metric int64 
11    CTR Percent {:.2f}%  Metric float64 
12    CTR Percent {:.2f}%  Metric float64 
13  Avg. CPC Currency ${:,.2f}  Metric float64 
14  Avg. CPC Currency ${:,.2f}  Metric float64 

>>> df2 
     Display Name  Type Format Behavior Datatype 
0   Match type String  {} Attribute object 
1 Destination URL Float {:.2f}  Metric float64 
2   Final URL Float {:.2f}  Metric float64 
3 Mobile final URL Float {:.2f}  Metric float64 
4    Labels String  {} Attribute object 
5  Impressions Integer {:,.0f}  Metric int64 
6    Clicks Integer {:,.0f}  Metric int64 
7    CTR String  {} Attribute object 
8   Avg. CPC Float {:.2f}  Metric float64 
9    Cost Float {:.2f}  Metric float64 
10  Avg. position Float {:.2f}  Metric float64 

>>> df2_vals_in_df1 
    Display Name  Type Format Behavior Datatype 
5 Impressions Integer {:,.0f}  Metric int64 
6  Clicks Integer {:,.0f}  Metric int64 
7   CTR String  {} Attribute object 
8  Avg. CPC Float {:.2f}  Metric float64 

>>> df1_vals_in_df2 
    Display Name  Type Format Behavior Datatype 
7 Impressions Integer {:,.0f} Metric int64 
8 Impressions Integer {:,.0f} Metric int64 
9  Clicks Integer {:,.0f} Metric int64 
10  Clicks Integer {:,.0f} Metric int64 
11   CTR Percent {:.2f}% Metric float64 
12   CTR Percent {:.2f}% Metric float64 
13  Avg. CPC Currency ${:,.2f} Metric float64 
14  Avg. CPC Currency ${:,.2f} Metric float64 

注意。それらのTypeFormatBehaviorDatatypeの値は、常に両方の行で同じ値になります。 df2

予想される出力:

>>> df2 
     Display Name  Type Format Behavior Datatype 
0   Match type String  {} Attribute object 
1 Destination URL Float {:.2f}  Metric float64 
2   Final URL Float {:.2f}  Metric float64 
3 Mobile final URL Float {:.2f}  Metric float64 
4    Labels String  {} Attribute object 
5  Impressions Integer {:,.0f}  Metric int64 <-- same 
6    Clicks Integer {:,.0f}  Metric int64 <-- same 
7    CTR Percent {:.2f}%  Metric float64 <-- changed 
8   Avg. CPC Currency ${:,.2f}  Metric float64 <-- changed 
9    Cost Float {:.2f}  Metric float64 
10  Avg. position Float {:.2f}  Metric float64 

テイクアウト#1:行5、彼らはdf1df2の両方で同じであるため、6が同じです。

テイクアウト#2String, {}, Attribute, objectPercent, {:.2f}%, Metric, float64から変更行7、 - df2からDisplay Namedf1Display Nameで見つかったため、df1から行の値。

テイクアウェイ#3:行8は、テイクアウェイ#2で述べられているのと同じ理由で変更されました。

が試み:

Q1:Python Pandas: Merge or Filter DataFrame by Another. Is there a Better Way?

私は新しいデータフレームを作成しようとしていないよので、この質問には対応していません。私は既存のデータフレームの値を別のものから置き換えることを試みています。

Q2:この例は、正しい値を持つ1人のDFが含まれているため、私の状況は正しいと間違った値を持つDFであるのに対し、Replace column values based on another dataframe python pandas - better way?

は、この質問には対応していません。

これは長い質問です。私はちょうど十分な文脈を提供したかった。

+2

さて、あなたはDF1を縮小することによって、より読みやすい本を作ることができるし、実質的にdf2である。 5行2列は、同じように簡単にポイントを取得します。あなたが 'combine_first()'を探しているだけですか? – JohnE

+0

フィードバックいただきありがとうございます。おそらくTMI(あまりにも多くの情報)でした。私はあなたの提案 'combine_first()'を使って解決策を見つけました。しかし、重複排除が必要な行が追加されるため、私はそれを嫌っています。第2に、上記の期待される出力を得るために、私はウィザード型のカスタムマッピングを行う必要があります。 – Jarad

答えて

2

私は、combine_firstが、JohnEによると、Display Nameをインデックスとして設定すると、洗練されたソリューションになると思います。これは別のポイントに私をもたらします。私はあなたの仕事は、 '表示名'が各テーブル内の正確に1組の属性に対応する場合にのみ、明確に定義されていると思います。あなたは、重複をドロップし、インデックスなどのような.updateを使用することができ、と仮定すると:

df1 = df1.drop_duplicates() 

df1 = df1.set_index('Display Name') 
df2 = df2.set_index('Display Name') 

df2_c = df2.copy() 

df2.update(df1) 
df1.update(df2_c) 

del df2_c 

あなたが好きな場合は、補助指標とdf1の寸法をリセットすることができます。

+0

[更新()](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.update.html)のドキュメントでは、「インデックスに合わせる」と記載されています。それで、インデックスを「表示名」に設定するのはなぜですか? – Jarad

+0

はい、そうです。 –

+0

この回答を正しいと受け入れます。しかし、この回答は上記の私のQ1と非常によく似ています。そして、誰も(私自身を除いて)答えを出した人はいません。だから...最高の答え。 – Jarad

0

理想的ではありませんが、予想される出力を再現することができました。問題は、私はdf3を作成することを避けたいと思っており、これは理想的ではないので、すべてdf2内に置き換えたいと思います。

df2前:

 Display Name  Type Format Behavior Datatype 
0   Match type String  {} Attribute object 
1 Destination URL Float {:.2f}  Metric float64 
2   Final URL Float {:.2f}  Metric float64 
3 Mobile final URL Float {:.2f}  Metric float64 
4    Labels String  {} Attribute object 
5  Impressions Integer {:,.0f}  Metric int64 
6    Clicks Integer {:,.0f}  Metric int64 
7    CTR String  {} Attribute object 
8   Avg. CPC Float {:.2f}  Metric float64 
9    Cost Float {:.2f}  Metric float64 
10  Avg. position Float {:.2f}  Metric float64 

df3後:

df3 = df2.combine_first(df1).drop_duplicates('Display Name', keep='last') 
df3 = df3.set_index(df3['Display Name'].map(dict(zip(df2['Display Name'], df2.index)))).sort_index().reset_index(drop=True) 

     Display Name  Type Format Behavior Datatype 
0   Match type String  {} Attribute object 
1 Destination URL  Float {:.2f}  Metric float64 
2   Final URL  Float {:.2f}  Metric float64 
3 Mobile final URL  Float {:.2f}  Metric float64 
4    Labels String  {} Attribute object 
5  Impressions Integer {:,.0f}  Metric int64 
6    Clicks Integer {:,.0f}  Metric int64 
7    CTR Percent {:.2f}%  Metric float64 
8   Avg. CPC Currency ${:,.2f}  Metric float64 
9    Cost  Float {:.2f}  Metric float64 
10  Avg. position  Float {:.2f}  Metric float64 

df2前と比較した後:

Display Name Type Format Behavior Datatype 
0   True True True  True  True 
1   True True True  True  True 
2   True True True  True  True 
3   True True True  True  True 
4   True True True  True  True 
5   True True True  True  True 
6   True True True  True  True 
7   True False False False False 
8   True False False  True  True 
9   True True True  True  True 
10   True True True  True  True