比较 groupby 内的字符串行并将值分配给新列 pandas
Comparing rows of string inside groupby and assigning a value to a new column pandas
我有一个员工(他们的 ID)和他们老板名字的数据集,已经有好几年了。
df:
我需要做的是看看员工有没有老板的变化。因此,所需的输出是:
对于只在df中出现过一次的员工,我只分配0(没有老板的变化)。但是,对于在df工作了几年的员工,我想不通该怎么做。
我在想首先我需要为他们出现在df中的第一年分配0(因为我们不知道以前谁是老板,所以没有老板的变化)。然后我需要将老板的名字与下一行中的名字进行比较,并决定是否将 1 或 0 分配到 ManagerChange 列中。
到目前为止,我将 df 分成两部分(具有唯一 ID 和重复 ID)并将 0 分配给 ManagerChange 作为唯一 ID。
然后我将重复的 ID 分组并按年份对它们进行排序。但是,我是 Python 的新手,不知道如何比较字符串并将结果值分配给 groupby 内的新列。请帮忙。
我目前拥有的代码:
# splitting database in two
bool_series = df["ID"].duplicated(keep=False)
df_duplicated=df[bool_series]
df_unique = df[~bool_series]
# assigning 0 for ManagerChange for the unique IDs
df_unique['ManagerChange'] = 0
# groupby by ID and sorting by year for the duplicated IDs
df_duplicated.groupby('ID').apply(lambda x: x.sort_values('Year'))
您可以分组,然后 shift()
分组并比较 Boss
列。
# Sort value first
df.sort_values(['ID', 'Year'], inplace=True)
# Compare Boss column with shifted Boss column
df['ManagerChange'] = df.groupby('ID').apply(lambda group: group['Boss'] != group['Boss'].shift(1)).tolist()
# Change True to 1, False to 0
df['ManagerChange'] = df['ManagerChange'].map({True: 1, False: 0})
# Sort df to original df
df = df.sort_index()
# Change the first in each group to 0
df.loc[df.groupby('ID').head(1).index, 'ManagerChange'] = 0
# print(df)
ID Year Boss ManagerChange
0 1234 2018 Anna 0
1 567 2019 Sarah 0
2 1234 2020 Michael 0
3 8976 2019 John 0
4 1234 2019 Michael 1
5 8976 2020 John 0
您也可以使用 fill_value
参数,这将帮助您摆脱最后的 df.loc[]
操作。
# Sort value first
df.sort_values(['ID', 'Year'], inplace=True)
df['ManagerChange'] = df.groupby('ID').apply(lambda group: group['Boss'] != group['Boss'].shift(1, fill_value=group['Boss'].iloc[0])).tolist()
# Change True to 1, False to 0
df['ManagerChange'] = df['ManagerChange'].map({True: 1, False: 0})
# Sort df to original df
df = df.sort_index()
我有一个员工(他们的 ID)和他们老板名字的数据集,已经有好几年了。
df:
我需要做的是看看员工有没有老板的变化。因此,所需的输出是:
对于只在df中出现过一次的员工,我只分配0(没有老板的变化)。但是,对于在df工作了几年的员工,我想不通该怎么做。
我在想首先我需要为他们出现在df中的第一年分配0(因为我们不知道以前谁是老板,所以没有老板的变化)。然后我需要将老板的名字与下一行中的名字进行比较,并决定是否将 1 或 0 分配到 ManagerChange 列中。
到目前为止,我将 df 分成两部分(具有唯一 ID 和重复 ID)并将 0 分配给 ManagerChange 作为唯一 ID。
然后我将重复的 ID 分组并按年份对它们进行排序。但是,我是 Python 的新手,不知道如何比较字符串并将结果值分配给 groupby 内的新列。请帮忙。
我目前拥有的代码:
# splitting database in two
bool_series = df["ID"].duplicated(keep=False)
df_duplicated=df[bool_series]
df_unique = df[~bool_series]
# assigning 0 for ManagerChange for the unique IDs
df_unique['ManagerChange'] = 0
# groupby by ID and sorting by year for the duplicated IDs
df_duplicated.groupby('ID').apply(lambda x: x.sort_values('Year'))
您可以分组,然后 shift()
分组并比较 Boss
列。
# Sort value first
df.sort_values(['ID', 'Year'], inplace=True)
# Compare Boss column with shifted Boss column
df['ManagerChange'] = df.groupby('ID').apply(lambda group: group['Boss'] != group['Boss'].shift(1)).tolist()
# Change True to 1, False to 0
df['ManagerChange'] = df['ManagerChange'].map({True: 1, False: 0})
# Sort df to original df
df = df.sort_index()
# Change the first in each group to 0
df.loc[df.groupby('ID').head(1).index, 'ManagerChange'] = 0
# print(df)
ID Year Boss ManagerChange
0 1234 2018 Anna 0
1 567 2019 Sarah 0
2 1234 2020 Michael 0
3 8976 2019 John 0
4 1234 2019 Michael 1
5 8976 2020 John 0
您也可以使用 fill_value
参数,这将帮助您摆脱最后的 df.loc[]
操作。
# Sort value first
df.sort_values(['ID', 'Year'], inplace=True)
df['ManagerChange'] = df.groupby('ID').apply(lambda group: group['Boss'] != group['Boss'].shift(1, fill_value=group['Boss'].iloc[0])).tolist()
# Change True to 1, False to 0
df['ManagerChange'] = df['ManagerChange'].map({True: 1, False: 0})
# Sort df to original df
df = df.sort_index()