猿问

连接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的情况下做到这一点,这对于大数据帧是不切实际的。谢谢


犯罪嫌疑人X
浏览 63回答 2
2回答

BIG阳

由于连接后需要名称的详细信息,因此不应删除它们。df's您需要将名称添加为列,以便在连接后,我们可以知道哪一行来自哪一行。dfdf>>> 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           origin0      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]您需要执行一个热编码才能获得预期的结果,例如,(从这里引用)使用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  df30    0    1    01    1    0    02    0    0    13    0    1    04    1    1    15    1    0    1最后>>> pd.concat([df.drop('origin', axis=1), encoded_df], axis=1)   user_id username firstname lastname  df1  df2  df30      111      xyz       xyz      xyz    0    1    01      123      abc       abc      abc    1    0    02      222      uwv       uwv      uwv    0    0    13      234      mnp       mnp      mnp    0    1    04      456      def       def      def    1    1    15      789      ghi       ghi      ghi    1    0    1

千巷猫影

创建 DataFrames 的字典,因此,如果创建了 concat,则通过DataFrame.reset_index将其转换为列,并按所有列进行分组,因此最后可以使用 Series.str.get_dummies:MultiIndexjoinreset_indexdfs = {'df1': df1, 'df2': df2, 'df3': df3}df = (pd.concat(dfs)       .reset_index()       .groupby(df1.columns.tolist())['level_0']       .apply('|'.join)       .str.get_dummies()       .reset_index())print (df)   user_id username firstname lastname  df1  df2  df30      111      xyz       xyz      xyz    0    1    01      123      abc       abc      abc    1    0    02      222      uwv       uwv      uwv    0    0    13      234      mnp       mnp      mnp    0    1    04      456      def       def      def    1    1    15      789      ghi       ghi      ghi    1    0    1
随时随地看视频慕课网APP

相关分类

Python
我要回答