concatはPythonのデータフレームは、重複削除し、行の起源の記録を保持します

タングエン:

私は、複数のデータフレーム、例えば、データを持っています:

DF1:

user_id    username firstname lastname 
 123         abc      abc       abc
 456         def      def       def 
 789         ghi      ghi       ghi

DF2:

user_id     username  firstname lastname
 111         xyz       xyz       xyz
 456         def       def       def
 234         mnp       mnp       mnp

DF3:

user_id     username  firstname lastname
 789         ghi       ghi       ghi       
 456         def       def       def
 222         uwv       uwv       uwv       

私は、これらのデータフレームを連結重複行を削除し、より多くの列を追加することによって、行の起源を追跡します。所望の出力:

DF1:

user_id    username firstname lastname df1 df2 df3
 123         abc       abc       abc    1   0   0
 456         def       def       def    1   1   1
 789         ghi       ghi       ghi    1   0   1
 111         xyz       xyz       xyz    0   1   0
 234         mnp       mnp       mnp    0   1   0
 222         uwv       uwv       uwv    0   0   1      

私が使用して最初のステップを行う連結することができます。

pd.concat([df1, df2, df3]).drop_duplicates('user_id').reset_index(drop=True)

どのように私は最後のステップ(原点列を作る)を行うことができますか?私は大きなデータフレームのための実用的ではないforloop、なしでこれを行う方法を知りません。ありがとうございました

shaikはmoeed:

あなたはの詳細必要があるとして、df's連結後の名前を、あなたがそれらをドロップするべきではありません。

あなたは追加する必要がdf連結した後、私たちはそこからである行、知ることができるように、列として名前をdf

>>> cols = df1.columns.to_list() # Store columns before adding `origin` column to use later in groupby
>>> df1['origin'] = 'df1'
>>> df2['origin'] = 'df2'
>>> df3['origin'] = 'df3'

今、使ってgroupbyあなたのタスクが容易になります。

>>> df = pd.concat([df1, df2, df3])\
    .reset_index(drop=True)\
    .groupby(by = cols, axis=0)\
    .apply(lambda x: x['origin'].values)\
    .to_frame('origin')\
    .reset_index()

出力:

>>> df

   user_id username firstname lastname           origin
0      111      xyz       xyz      xyz            [df2]
1      123      abc       abc      abc            [df1]
2      222      uwv       uwv      uwv            [df3]
3      234      mnp       mnp      mnp            [df2]
4      456      def       def      def  [df1, df2, df3]
5      789      ghi       ghi      ghi       [df1, df3]

あなたは(から参照、のような期待どおりの結果を得るために、1つのホットエンコーディングを行う必要があり、ここで

使用sklearn.preprocessing.MultiLabelBinarizerを(あなたが使用することもできpd.get_dummies確認し、同様にこれを

>>> from sklearn.preprocessing import MultiLabelBinarizer
>>> mlb = MultiLabelBinarizer()
>>> expandedLabelData = mlb.fit_transform(df["origin"])
>>> labelClasses = mlb.classes_
>>> encoded_df = pd.DataFrame(expandedLabelData, columns=labelClasses)
   df1  df2  df3
0    0    1    0
1    1    0    0
2    0    0    1
3    0    1    0
4    1    1    1
5    1    0    1

最後に、

>>> pd.concat([df.drop('origin', axis=1), encoded_df], axis=1)
   user_id username firstname lastname  df1  df2  df3
0      111      xyz       xyz      xyz    0    1    0
1      123      abc       abc      abc    1    0    0
2      222      uwv       uwv      uwv    0    0    1
3      234      mnp       mnp      mnp    0    1    0
4      456      def       def      def    1    1    1
5      789      ghi       ghi      ghi    1    0    1

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=27941&siteId=1