【问题标题】:Pandas: use a timeseries as a mask for selectionPandas:使用时间序列作为选择的掩码
【发布时间】:2016-12-07 21:04:49
【问题描述】:

我尝试使用蒙版从我的 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

【问题讨论】:

  • 能输出s1和s2的head吗?执行print(s1.head())print(s2.head()) 并在此处复制并粘贴输出

标签: python pandas selection


【解决方案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

【讨论】:

  • 像魅力一样工作,比我想出的方法干净得多。
【解决方案2】:

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

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

您可以执行以下操作:

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

【讨论】:

  • 谢谢,这也有效。但是,我想要的是所有条目,正如您所提到的,@jezraels 解决方案非常适合。
【解决方案3】:

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

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 方法,因为我认为它更干净。

【讨论】:

    猜你喜欢
    • 2013-05-04
    • 2016-01-30
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 2018-04-24
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多