我尝试使用掩码从我的groupby对象中进行选择,但是我得到了一个我无法解决的错误。
首先我按groupid分组
df_grouped = df.groupby('groupid')
然后我计算了每组中的STD,min和max,以便在我的选择面具中使用。
df_grouped_std = df_grouped.std()
df_grouped_min = df_grouped.min()
df_grouped_max = df_grouped.max()
然后我在不同的参数上创建两个掩码。
s1 = df_grouped_std['distance']<0.05
s2 = (df_grouped_max.speed- df_grouped_min.speed) < 10
最后我结合了面具。
sTot = s1&s2
这会产生以下错误/ stacktrace:
Traceback (most recent call last):
File "<ipython-input-198-b0df7aa8bb76>", line 1, in <module>
selection = df_grouped[sTot.values]
File "C:\Anaconda\lib\site-packages\pandas\core\groupby.py", line 3155, in __getitem__
% str(bad_keys)[1:-1])
KeyError: 'Columns not found: False, True'
之后我想用掩码来选择。
selection = df_grouped[sTot]
我看到s1,s2和Stot是时间序列,也许这就是为什么我不能用它们来选择,但我无法弄清楚为什么会这样。我在这里缺少什么?
数据示例:
print(s1.head())
print(s2.head())
print(sTot.head())
groupid
941 True
942 True
1721 True
1722 True
2201 True
Name: distance, dtype: bool
groupid
941 True
942 True
1721 False
1722 True
2201 False
Name: speed, dtype: bool
groupid
941 True
942 True
1721 False
1722 True
2201 False
dtype: bool
答案 0 :(得分:1)
我认为您可以使用filter:
print (df.groupby('groupID')
.filter(lambda x: (x.distance.std() < 0.05) &
((x.speed.max()- x.speed.min()) < 10)))
示例(已更改0.05
至1
):
df = pd.DataFrame({'groupID':[1,1,3,3],
'speed':[4,5,6,1],
'distance':[1,2,3,1]})
print (df)
distance groupID speed
0 1 1 4
1 2 1 5
2 3 3 6
3 1 3 1
print (df.groupby('groupID')
.filter(lambda x: (x.distance.std() < 1) &
((x.speed.max()- x.speed.min()) < 10)))
distance groupID speed
0 1 1 4
1 2 1 5
答案 1 :(得分:1)
你想要什么结果?您是否希望所有组中的条目(条件所在的条目),或者只是组的聚合信息?
我认为@jezrael的解决方案很好,如果你想要所有参赛作品。顺便说一下,你可能会发现.get_group()很有用。
您可以执行以下操作:
for k, v in sTot.iteritems():
if v == True:
print df_grouped.get_group(k)
答案 2 :(得分:0)
我想出了另一个解决方案。在问题中的代码之后:
df_grouped = df.groupby('groupid')
df_grouped_std = df_grouped.std()
df_grouped_min = df_grouped.min()
df_grouped_max = df_grouped.max()
s1 = df_grouped_std['distance']<0.05
s2 = (df_grouped_max.speed- df_grouped_min.speed) < 10
我确实在df_grouped_std
上应用了所有选择sTot2 = df_grouped_std[s1][s2][s3][s4][s5]
然后我使用所选列的索引值,并从原始(未分组)数据帧中选择那些。最后我再次分组,因为我需要这些小组。
selection = sTot2.index.get_level_values(0)
selected_groups = df[df.ROL_IDENT.isin(selection)].groupby('ROL_IDENT')
虽然这有效,但我更喜欢@jezraels方法,因为我认为它更清洁。