根据其他列的条件为pandas列分配值

4

我有一个数据框:

df_test = pd.DataFrame({'col': ['paris', 'paris', 'nantes', 'berlin', 'berlin', 'berlin', 'tokyo'],
                        'id_res': [12, 12, 14, 28, 8, 4, 89]})


     col  id_res
0   paris      12
1   paris      12
2  nantes      14
3  berlin      28
4  berlin       8
5  berlin       4
6   tokyo      89

我想创建一个“检查”列,其值如下:

  • 如果“col”中的一个值有重复,并且这些重复具有相同的id_res,则对于重复项,“check”的值为False
  • 如果“col”中的一个值有重复项,并且这些重复项的“id_res”不同,则对于最大的“id_res”值,在“check”中分配True,在最小的值上分配False
  • 如果“col”中的一个值没有重复,则“check”的值为False。

因此,我想要的输出结果是:

    col  id_res  check
0   paris      12  False
1   paris      12  False
2  nantes      14  False
3  berlin      28   True
4  berlin       8  False
5  berlin       4  False
6   tokyo      89  False

我尝试了groupby,但没有令人满意的结果。有人可以帮帮我吗?

2个回答

7
创建两个布尔掩码,然后组合它们并找到每个col的最高id_res值。
m1 = df['col'].duplicated(keep=False)
m2 = ~df['id_res'].duplicated(keep=False)
df['check'] = df.index.isin(df[m1 & m2].groupby('col')['id_res'].idxmax())
print(df)

# Output
      col  id_res  check
0   paris      12  False
1   paris      12  False
2  nantes      14  False
3  berlin      28   True
4  berlin       8  False
5  berlin       4  False
6   tokyo      89  False

详细信息:

>>> pd.concat([df, m1.rename('m1'), m2.rename('m2')])
      col  id_res  check     m1     m2
0   paris      12  False   True  False
1   paris      12  False   True  False
2  nantes      14  False  False   True
3  berlin      28   True   True   True  # <-  group to check
4  berlin       8  False   True   True  # <-     because 
5  berlin       4  False   True   True  # <- m1 and m2 are True
6   tokyo      89  False  False   True

总之,你有三个条件,所以我认为使用三个掩码更加明确;) - mozway
也许,但你必须对m2和m3分别评估该组两次。起初我几乎有同样的解决方案,但我认为逐列检查1个条件更明显,然后在第二次检查组的最高值。问题在于视角 :) - Corralien
而且transform也不是那么显然!解释一下广播 :) - Corralien

5
你基本上有3个条件,所以使用掩码并取逻辑交集(AND /&):
g = df_test.groupby('col')['id_res']

# is col duplicated?
m1 = df_test['col'].duplicated(keep=False)
# [ True  True False  True  True  True False]

# is id_res max of its group?
m2 = df_test['id_res'].eq(g.transform('max'))
# [ True  True  True  True False False  True]

# is group diverse? (more than 1 id_res)
m3 = g.transform('nunique').gt(1)
# [False False False  True  True  True False]

# check if all conditions True
df_test['check'] = m1&m2&m3

输出:

      col  id_res  check
0   paris      12  False
1   paris      12  False
2  nantes      14  False
3  berlin      28   True
4  berlin       8  False
5  berlin       4  False
6   tokyo      89  False

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接