如何使用逻辑运算符筛选Pandas分类类型列的DataFrame行
解决Pandas有序分类列的逻辑筛选问题
这问题我之前踩过坑!核心原因是有序CategoricalDtype的比较逻辑是基于它预定义的类别顺序,而不是直接和原始数值做运算。你直接写df['bin'] > 50时,Pandas没法把数值50和分类区间对应起来,自然就抛出错误了。
下面给你两种实用的解决方案,结合你的示例代码来演示:
方法一:利用有序分类的类型特性(推荐)
因为你用pd.cut生成的是有序分类,我们可以先把数值50转换成对应的分类区间,再用分类类型本身的比较逻辑来筛选:
import pandas as pd import numpy as np # 你的原始代码 df = pd.DataFrame(np.random.randint(0,100,size=150), columns=['whatever']) df_bins = np.linspace(df.min(), df.max(), 101) df['bin'] = pd.cut(df.iloc[:,0], df_bins) # 生成包含50的目标分类区间 target_bin = pd.cut([50], bins=df_bins)[0] # 直接用有序分类的比较逻辑筛选 filtered_df = df[df['bin'] > target_bin]
为什么这个方法可行?因为target_bin和df['bin']是同类型的有序分类,Pandas会基于类别定义的顺序(也就是区间从小到大的顺序)来判断大小,完美避开数值和分类类型不兼容的问题。
方法二:提取区间边界转为数值后筛选
如果你觉得分类类型的逻辑太绕,也可以把分类区间的边界提取成数值列,再用常规的数值比较筛选:
# 提取每个区间的左边界作为数值列 df['bin_left'] = df['bin'].apply(lambda x: x.left) # 筛选左边界大于50的行 filtered_df = df[df['bin_left'] > 50] # 或者提取右边界(根据你的需求选择) df['bin_right'] = df['bin'].apply(lambda x: x.right) filtered_df = df[df['bin_right'] > 50]
这个方法更直观,适合刚接触分类类型的同学,但需要注意:apply会遍历每一行,数据量大的时候效率会比方法一低一些。
内容的提问来源于stack exchange,提问作者mfastudillo
相关产品推荐
相关产品推荐

