能否使用方法链(method chaining)结合条件删除DataFrame行?
Pandas方法链实现行过滤与列删除的正确写法
原始数据与前置操作
先看初始的DataFrame以及生成AwayTeam列的代码:
import pandas as pd df = pd.DataFrame({'Country': ["Uruguay", "Italy", "France"], 'Winner': ["Uruguay", "Italy", "France"]}) def f(row): if row['Country'] in row['Winner']: val = False else: val = True return val df["AwayTeam"] = df.apply(f, axis=1)
非链式的可行写法
你原本的非链式写法可以正常完成需求:
# 非链式写法 df.drop(df[df['AwayTeam'] == False].index, inplace = True) df = df.drop("AwayTeam", axis=1)
链式写法报错原因
你尝试的链式写法报错,核心问题是用了inplace=True——这个参数会让drop直接修改原DataFrame,返回值是None,后续再调用.drop就相当于在None对象上执行方法,必然报错。
正确的链式写法
写法一:去掉inplace,直接链式调用
# 正确链式写法1 df = ( df.drop(df[df['AwayTeam'] == False].index) .drop("AwayTeam", axis=1) )
写法二:用query过滤行,更简洁直观
比起通过索引删除行,用query直接过滤符合条件的行,代码可读性更强:
# 正确链式写法2(推荐) df = ( df.query("AwayTeam == True") .drop("AwayTeam", axis=1) )
进阶:把生成AwayTeam列也加入链式流程
如果想把从创建DataFrame到最终结果的整个流程都用链式完成,可以用assign方法替代单独的列赋值,代码更紧凑:
# 完整链式流程 df = ( pd.DataFrame({'Country': ["Uruguay", "Italy", "France"], 'Winner': ["Uruguay", "Italy", "France"]}) .assign( AwayTeam=lambda x: x.apply(lambda row: row['Country'] not in row['Winner'], axis=1) ) .query("AwayTeam == True") .drop("AwayTeam", axis=1) )
内容的提问来源于stack exchange,提问作者Chery
相关产品推荐
相关产品推荐

