如何根据特定列中的值有条件地使用“pandas.DataFrame.apply”?

How to conditionally use `pandas.DataFrame.apply` based on values in a certain column?

我有一个 pandas DataFrame,我正在使用 pandas.DataFrame.apply()

dict1 = {'file': ['filename2', 'filename2', 'filename3', 'filename4', 
         'filename4', 'filename3'], 'amount': [3, 4, 5, 1, 2, 1], 
         'front': [21889611, 36357723, 196312, 11, 42, 1992], 
         'back':[21973805, 36403870, 277500, 19, 120, 3210], 
         'type':['A', 'A', 'A', 'B', 'B', 'C']}

df1 = pd.DataFrame(dict1)
print(df1)

        file  amount     front      back type
0  filename2       3  21889611  21973805    A
1  filename2       4  36357723  36403870    A
2  filename3       5    196312    277500    A
3  filename4       1        11        19    B
4  filename4       2        42       120    B
5  filename3       1      1992      3210    C

我的任务是在 frontback 列之间进行 N 随机抽取,其中 N 等于 amount 列中的值:

def my_func(x):
    return np.random.choice(np.arange(x.front, x.back+1), x.amount).tolist()

我只想将此函数应用于 type 等于 A 的行。

如果我没有条件,我会使用 pd.DataFrame.apply() 如下:

df1["new_column"] = df1.apply(my_func, axis=1)

要仅在 type==A 时应用它,我可以做类似

的事情
if set(['A']).issubset(df1['type']):
    df1["new_column"] = df1.apply(my_func, axis=1)

然而,这实际上不起作用---my_func适用于所有功能。

(1) 为什么上面没有按预期工作?

(2) 如何有效地将 my_func 应用于满足 type==A 的行?在上面的示例中,这将是前三行,接下来的三行将是 NA

先过滤数据框,然后应用 my_func。让我们使用 query:

df1['new_column'] = df1.query('type == "A"').apply(my_func, axis=1)

输出:

   amount      back       file     front type  \
0       3  21973805  filename2  21889611    A   
1       4  36403870  filename2  36357723    A   
2       5    277500  filename3    196312    A   
3       1        19  filename4        11    B   
4       2       120  filename4        42    B   
5       1      3210  filename3      1992    C   

                                 new_column  
0            [21921030, 21908574, 21971743]  
1  [36391053, 36371413, 36394390, 36376405]  
2  [198648, 263355, 197017, 261666, 260815]  
3                                       NaN  
4                                       NaN  
5                                       NaN