Groupby 特定列然后根据条件分配新值

Groupby specific column then assign new values base on conditions

我有一个如下所示的数据框。

Name    M_Name       Tag        
John                  1
Dave      a           1
Mary                  1      
Sam                   1     
Chris     a           1
John                  2
Nola      f           2
Chuck                 2      
Rob                   2     
Chris     a           2
Angie                 3
Joe                   3
 :        :           : 
Tony                  n    

我需要创建一个新列 Tag_2,它基于 Tag 列和 M_Name 列。首先,我需要对 Tag 列进行分组,然后如果 M_Name 列有超过 1 个不同的字母,整个 Tag 组将在 Tag_2 列下有一个新值“Invalid”。如果同一标签组的 M-Name 中只有 1 个字母,则它将是“有效的”。 输出应该是这样的。

Name    M_Name       Tag          Tag_2       
John                  1           Valid
Dave      a           1           Valid
Mary                  1           Valid           
Sam                   1           Valid     
Chris     a           1           Valid
John                  2          Invalid
Nola      f           2          Invalid          
Chuck                 2          Invalid      
Rob                   2          Invalid     
Chris     a           2          Invalid
Angie                 3           Valid
Joe                   3           Valid
 :        :           : 
Tony                  n           Valid    

标签 2 组“无效”,因为 M_Name 行对于标签 2 组有超过 1 个不同的字母(f 和 a)。

我正在考虑使用 groupby 来解决这个任务,但我不知道如何添加这样的条件。 df.groupby('Tag')['M_Name'] 我想知道我是否在使用 groupby 的正确路径上,或者是否有我应该考虑的更好的方法?

谢谢!

我确定有更好的方法,但这是一个解决方案:

def validate(s):
    return "Invalid" if len(set(s)) > 2 else "Valid"


mapping = df.groupby("Tag")["M_Name"].apply(validate)
df["Tag_2"] = df.loc[:, "Tag"].replace(mapping)

输出:

     Name M_Name  Tag    Tag_2
0    John           1    Valid
1    Dave      a    1    Valid
2    Mary           1    Valid
3     Sam           1    Valid
4   Chris      a    1    Valid
5    John           2  Invalid
6    Nola      f    2  Invalid
7   Chuck           2  Invalid
8     Rob           2  Invalid
9   Chris      a    2  Invalid
10  Angie           3    Valid
11    Joe           3    Valid

首先,我们 group(),然后我们 transform() M_Name 列,其中 lambda 我们过滤掉空值 x[x.ne('')],然后使用 value_counts()获取元素出现频率,根据元素个数判断有效性:

df = pd.DataFrame(
    {'Name': ['John', 'Dave', 'Mary', 'Sam', 'Chris', 'John', 'Nola', 'Chuck', 'Rob', 'Chris', 'Angie', 'Joe'],
     'M_Name': ['', 'a', '', '', 'a', '', 'f', '', '', 'a', '', ''], 'Tag': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3]})

df['Tag2'] = df.groupby('Tag').M_Name.transform(
    lambda x: 'Invalid' if x[x.ne('')].value_counts().shape[0] > 1 else 'Valid')
print(df)

输出:

     Name M_Name  Tag     Tag2
0    John           1    Valid
1    Dave      a    1    Valid
2    Mary           1    Valid
3     Sam           1    Valid
4   Chris      a    1    Valid
5    John           2  Invalid
6    Nola      f    2  Invalid
7   Chuck           2  Invalid
8     Rob           2  Invalid
9   Chris      a    2  Invalid
10  Angie           3    Valid
11    Joe           3    Valid