pandas 根据另一列值创建“是”列panda Dataframe

dwbf0jvd  于 2023-01-07  发布在  其他
关注(0)|答案(2)|浏览(170)

假设我有一个包含员工ID、合同号和工作公司的 Dataframe ,每个员工可以在同一家公司甚至不同的公司拥有任意多份合同:

ID  Contract Number Company
10000   1           Abc
10000   2           Zxc
10000   3           Abc
10001   1           Zxc
10002   2           Abc
10002   1           Cde
10002   3           Zxc

我需要找到一种方法来标识每个ID的合同编号“1”的公司,然后创建一列“Primary Contract”,如果该合同与合同编号1的公司属于同一公司,则该列将设置为“Yes”,从而产生以下 Dataframe :

ID  Contract Number Company Primary Compay
10000   1            Abc           Yes
10000   2            Zxc           No
10000   3            Abc           Yes
10001   1            Zxc           Yes
10002   2            Abc           No
10002   1            Cde           Yes
10002   3            Zxc           No

实现这一目标的最佳途径是什么?

gg58donl

gg58donl1#

您可以将groupby.applyisinnumpy.where一起使用:

df['Primary Company'] = np.where(
 df.groupby('ID', group_keys=False)
   .apply(lambda g: g['Company'].isin(g.loc[g['Contract Number'].eq(1), 'Company'])
         ),
 'Yes', 'No'
)

输出:

ID  Contract Number Company Primary Company
0  10000                1     Abc             Yes
1  10000                2     Zxc              No
2  10000                3     Abc             Yes
3  10001                1     Zxc             Yes
4  10002                2     Abc              No
5  10002                1     Cde             Yes
6  10002                3     Zxc              No

如果您可以使用布尔值(True/False)代替'Yes'/'No'

df['Primary Company'] = (
 df.groupby('ID', group_keys=False)
   .apply(lambda g: g['Company'].isin(g.loc[g['Contract Number'].eq(1), 'Company']))
)
g6ll5ycj

g6ll5ycj2#

筛选Contract Number1的行,在DataFrame.merge中使用左连接,并比较indicator=True参数生成的_merge列:

mask = (df.merge(df[df['Contract Number'].eq(1)],
                how='left', on=['ID','Company'], indicator=True)['_merge'].eq('both'))
df['Primary Company'] = np.where(mask, 'Yes','No')
print (df)
      ID  Contract Number Company Primary Company
0  10000                1     Abc             Yes
1  10000                2     Zxc              No
2  10000                3     Abc             Yes
3  10001                1     Zxc             Yes
4  10002                2     Abc              No
5  10002                1     Cde             Yes
6  10002                3     Zxc              No

另一个想法是将MultiIndexIndex.isin进行比较:

idx = df[df['Contract Number'].eq(1)].set_index(['ID','Company']).index
df['Primary Company'] = np.where(df.set_index(['ID','Company']).index.isin(idx),
                                 'Yes','No')
print (df)
      ID  Contract Number Company Primary Company
0  10000                1     Abc             Yes
1  10000                2     Zxc              No
2  10000                3     Abc             Yes
3  10001                1     Zxc             Yes
4  10002                2     Abc              No
5  10002                1     Cde             Yes
6  10002                3     Zxc              No

相关问题