Python中如何在apply行级函数中判断DataFrame是否为空
问题与解决方案
需求说明
需要实现:仅当DataFrame整体非空时,才执行行级函数(将每行作为单独实例处理);若DataFrame为空,则不执行任何操作。常规的if not df.empty:能正确实现该逻辑(如场景1),但将判断逻辑融入行级函数并通过df.apply(func, axis=1)调用时,无法达到预期效果(用户反馈场景2中即使DataFrame为空仍会触发函数执行)。
示例代码
初始化与去重
import pandas as pd df = pd.DataFrame({'Datetime': ['2020/01/30 14:00:00', '2020/01/30 14:00:00'], 'Item': ['Apple','Apple'], 'Cost': ['1','1'], }) # 去重后df变为空 df = df.drop_duplicates(keep = False)
场景1(正常工作)
if not df.empty: print(df['Datetime']) print(df['Item']) print(df['Cost']) else: pass
场景2(存在问题)
def func(row): # 用户反馈:即使df为空,此处仍会触发打印 print(len(row)) # 错误:此处判断的是行Series是否为空,而非整个DataFrame if not row.empty: print(row['Datetime']) print(row['Item']) print(row['Cost']) else: pass df.apply(func, axis = 1)
问题分析
- 当DataFrame为空时,
df.apply(func, axis=1)本应不会遍历任何行,理论上不会执行func。若出现触发打印的情况,可能是代码其他环节的问题,或是混淆了“空DataFrame”与“空行”的概念。 - 场景2的核心错误:
func接收的是每行的Series对象,而非整个DataFrame。Series.empty仅当Series长度为0时返回True,但每行Series的长度等于DataFrame的列数,因此if not row.empty:永远为真,无法实现对整个DataFrame是否为空的判断。
解决方案
方案1:先判断DataFrame是否为空,再执行apply
这是最直接的实现方式,将全局判断放在apply调用前,而非行级函数内部:
def func(row): print(len(row)) print(row['Datetime']) print(row['Item']) print(row['Cost']) # 先判断整个DataFrame状态,再决定是否执行行级函数 if not df.empty: df.apply(func, axis=1) else: pass
方案2:若需同时跳过空行(行内全为空)
如果DataFrame非空,但存在部分全空的行需要跳过,可在函数内部补充行级判断:
def func(row): # 判断当前行是否所有值为空 if not row.isna().all(): print(len(row)) print(row['Datetime']) print(row['Item']) print(row['Cost']) else: pass # 先确保DataFrame非空,再执行行级处理 if not df.empty: df.apply(func, axis=1)
内容的提问来源于stack exchange,提问作者tonydanza123
相关产品推荐
相关产品推荐

