根据条件分组并更新 python pandas

Group by and update based on condition python pandas

你好,我有一个 pandas 数据框,其中包含一个 ID 列和一个值列。

我想使用矢量化代码对每个 ID 进行“分组”,然后 运行 对组内每一行的每个值执行一个函数。如果函数中特定 ID returns 的每个值都是 False,我想从原始数据框中删除 ID 和所有对应的行。

def funct1(num):
    num = num**.5
    if num - int(num) == 0:
        return True
    else:
        return False

import pandas as pd
df = {
   'ID':['1','1','1','1','1','2','2','2','2','2','3','3','3','3','3'],
   'Percentage':[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]}
df = pd.DataFrame(df)

最终结果应该是:

df = {
   'ID':['1','1','1','1','1','2','2','2','2','2'],
   'Percentage':[7,8,9,10,11,12,13,14,15,16]}
df = pd.DataFrame(df)

在这里我们看到ID 3的每一行都被删除了,因为组内没有以int作为平方根的值。

我也想维护索引,因为在真实数据中,值不是像这个例子那样有序的。

答案应该是 return df 而不是 groupby 对象。

感谢您的帮助!

最佳

在你的情况下 groupbyfilter

out = df.groupby('ID').filter(lambda x : any((x['Percentage']**0.5).map(float.is_integer)))
Out[317]: 
  ID  Percentage
0  1           7
1  1           8
2  1           9
3  1          10
4  1          11
5  2          12
6  2          13
7  2          14
8  2          15
9  2          16

你不需要 groupby:

funct1 = lambda pct: pct.pow(0.5) - pct.pow(0.5).astype(int) == 0
out = df[df['ID'].isin(df.loc[funct1(df['Percentage']), 'ID'])]
>>> out
  ID  Percentage
0  1           7
1  1           8
2  1           9
3  1          10
4  1          11
5  2          12
6  2          13
7  2          14
8  2          15
9  2          16

性能

# @BENY
%timeit df.groupby('ID').filter(lambda x : any((x['Percentage']**0.5).map(float.is_integer)))
1.08 ms ± 14.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# @Corralien
%timeit df[df['ID'].isin(df.loc[funct1(df['Percentage']), 'ID'])]
651 µs ± 2.36 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)