我有一种情况,只有当数据帧不为空时,我才需要在代码中向前移动数据帧。如下图所示:
----- Filter 1 -------
Check if df.empty then return emptydf
else
----- Filter 2 ------
Check if df.empty then return emptydf
else
----- Filter 3 ------
return df
上面的代码写成如下(只是部分代码):
def filter_df(df):
df = df[df.somecolumn > 2].copy()
if df.empty:
return df
df = df[df.someother == 2].copy()
if df.empty:
return df
df = df[df.all <= 10].copy()
return df
如果我有很多这样的过滤器,它们希望数据框不为空,我需要在每个过滤器之后检查是否为空。有没有更好的方法来检查数据框是否为空,而不是在每个级别进行检查。
请您参考如下方法:
重复子集化你的数据框是昂贵的。重复复制您的数据框也可能很昂贵。预先计算大量的 bool 掩码也很昂贵。棘手的部分是找到一种在 for 中懒惰应用掩码的方法。循环。
虽然下面的功能性解决方案可能看起来很丑陋,但它确实解决了上述问题。这个想法是将 bool 掩码迭代地与聚合掩码组合。检查你的循环是否你的掩码有所有False值,而不是数据框是否为空。在逻辑末尾应用聚合掩码一次:
from operator import methodcaller
def filter_df(df):
masks = [('somecolumn', 'gt', 2),
('someother', 'eq', 2),
('all', 'le', 10)]
agg_mask = np.ones(len(df.index)).astype(bool) # "all True" mask
for col, op, val in masks:
mask = methodcaller(op, val)(df[col])
agg_mask = agg_mask & mask
if not agg_mask.any():
return df[agg_mask]
return df[agg_mask]
注意此解决方案系列比较运算符,例如 > , == , <=具有等价的功能 pd.Series.gt , pd.Series.eq , pd.Series.le .
