这个问题是我在此发布的前一个问题的续集:Slicing Pandas Dataframe according to number of lines。我有很好的答案解决了这个问题。然而,当以不同的方式尝试解决方案时,我没有得到我所期望的,尽管进行了许多测试,但我不明白为什么。
假设我有一个pandas数据帧df包含一个'Group'Id(当然可以在一个组中有很多对象)和一个数量,比如'R'。我想构建另一个df,其中包含至少4个对象的组,第4个对象,当按R排序时,低于R_min(我知道调用最大'R_min'听起来很奇怪,但它们是星系量级,是负的,越亮越明亮 - 或越高越明亮的绝对值)。这是针对该问题构建的模拟DataFrame:
df = pd.DataFrame({ 'R' : (-21,-21,-22,-3,-23,-24,-20,-19,-34,-35,-30,-5,-25,-6,-7,-22,-21,-10,-11,-12,-13,-14,-15),
....: 'Group': (1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5) })
我的问题的解决方案就是这个,它似乎完美无缺:
R_min = -18.8
df_processed = (df[df.Group.map(df.Group.value_counts().ge(4))]
.groupby('Group').filter(lambda x: np.any(x.sort_values('R').iloc[3] <= R_min)))
我同意,第3组是唯一一个受我约束的人。现在,为了验证并知道我的星系组目录是如何构建的,我检查那些至少有四个成员的人剩下的是什么。我希望像下面这样的代码完全相同:
df_left = (df[df.Group.map(df.Group.value_counts().ge(4))]
.groupby('Group').filter(lambda x: np.any(x.sort_values('R').iloc[3] > R_min)))
不幸的是,它没有:
这里最引人注目的是第3组也在df_left中!按R排序,第3组给出-35,-34,-30,-19,-5,其中第4个值为-19,低于-18.8。怎么会?选择方法错了吗?我该如何纠正?
非常感谢
答案 0 :(得分:1)
您收到此错误是因为x.sort_values('R').iloc[3]
正在对DataFrame进行排序,而不是仅包含列R
的系列。这意味着当您致电np.any
时,它会检查包括列Group
在内的任何列,以查看它是否大于R_min
,因为Group
的所有值均为正值这将返回true。
您的代码也非常不理想。你应该这样做:
R_min = -18.8
df.groupby('Group').filter(lambda x: (x.shape[0] >= 4) & (x['R'].nsmallest(4).iloc[-1] <= R_min))