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 方法,因为我认为它更干净。
我尝试使用遮罩从我的 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 方法,因为我认为它更干净。