2016-12-06 76 views
1

我尝试使用掩码从我的groupby对象中进行选择,但出现无法解析的错误。熊猫:使用时间序列作为掩模进行选择

首先,我按GROUPID

df_grouped = df.groupby('groupid') 

然后,我计算出的STD,最小值和最大值从每个组中我选择的口罩使用。

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 

这提供了以下错误/堆栈跟踪:

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

你能输出s1和s2的头吗?执行'print(s1.head())'和'print(s2.head())'并复制粘贴这里的输出 –

回答

1

我认为你可以使用filter

print (df.groupby('groupID') 
     .filter(lambda x: (x.distance.std() < 0.05) & 
          ((x.speed.max()- x.speed.min()) < 10))) 

样品(改变0.051):

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 
+0

我会试试这个。 – marqram

+0

工作像魅力,比我想出的方法更清洁。 – marqram

1

你想要的结果是什么?你是否希望所有条目在哪些组(条件成立的地方),还是仅仅是组的汇总信息?

我认为@jezrael的解决方案是好的,如果你想要所有的条目。顺便说一句,你可能会发现.get_group()有用。

你可以做到以下几点:

for k, v in sTot.iteritems(): 
    if v == True: 
     print df_grouped.get_group(k) 
+0

谢谢,这也可以。然而,我想要的是所有条目,正如你所提到的,@jezraels解决方案对此非常有用。 – marqram

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的方法,因为我认为它更清洁。