Pandas:使用时间序列作为选择的掩码

Pandas: use a timeseries as a mask for selection

我尝试使用遮罩从我的 groupby 对象中生成 selection,但出现无法解决的错误。

首先我按groupid分组

df_grouped = df.groupby('groupid')

然后我计算了每组的 STD、最小值和最大值,以用于我的 select 离子面罩。

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

这给出了以下 error/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'

之后我想用面膜select。

selection = df_grouped[sTot]

我看到 s1、s2 和 Stot 是时间序列,也许这就是我不能将它们用于 select 的原因,但我不明白为什么会这样。我在这里错过了什么?

数据示例:

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

我想你可以使用 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

你想要什么结果?您是想要哪些组(条件成立)中的所有条目,还是只需要这些组的聚合信息?

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

您可以执行以下操作:

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

我想出了另一个解决方案。题中代码后:

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

上应用了所有 select 离子
sTot2 = df_grouped_std[s1][s2][s3][s4][s5]

然后我使用 selected 列的索引值,以及 select 来自原始(未分组)数据框的索引值。最后我再次分组,因为我需要分组。

selection = sTot2.index.get_level_values(0)
selected_groups = df[df.ROL_IDENT.isin(selection)].groupby('ROL_IDENT')

虽然这可行,但我更喜欢@jezraels 方法,因为我认为它更干净。