繁体   English   中英

Pandas 带空组的 GroupBy 时间 idxmax 抛出异常

[英]Pandas GroupBy time idxmax w/ empty groups throws exception

我有一个包含数百万个事件的列表,这些事件及时存储在数据框df中。 df.head()给出 output:

                             rel_temp
timestamp                        
2016-04-04 10:41:07.663457   0.02
2016-04-04 11:05:44.382078  -0.05
2016-04-04 11:42:08.777205   0.01
2016-04-04 11:44:54.194832   0.08
2016-04-04 11:49:48.349108  -0.02

我按时间分组。

grouper = pd.Grouper(freq='10T')
grouped_df = df.groupby(grouper)

我想获得所有时间 windows 的 idxmin 和 idxmax,因为我需要知道是最小值还是最大值先出现。 任何时候 window包含我想要一个 NaN 值的测量值。

因此,对于上面的 df,我希望grouped_df['rel_temp'].idxmax()给出这个 output:

timestamp
2016-04-04 10:40:00        0
2016-04-04 10:50:00      NaN
2016-04-04 11:00:00        0
2016-04-04 11:10:00      NaN
2016-04-04 11:20:00      NaN
2016-04-04 11:30:00      NaN
2016-04-04 11:40:00        1
2016-04-04 11:50:00      NaN

但是,据我所知,当 groupby 可能包含空组时,无法使用idxmax()idxmin() 这样做会导致此异常:

File "/.venv/lib/python3.9/site-packages/pandas/core/groupby/groupby.py", line 947, in wrapper
    return self._python_apply_general(curried, self._obj_with_exclusions)
  File "/.venv/lib/python3.9/site-packages/pandas/core/groupby/groupby.py", line 1287, in _python_apply_general
    keys, values, mutated = self.grouper.apply(f, data, self.axis)
  File "/.venv/lib/python3.9/site-packages/pandas/core/groupby/ops.py", line 820, in apply
    res = f(group)
  File "/.venv/lib/python3.9/site-packages/pandas/core/groupby/groupby.py", line 936, in curried
    return f(x, *args, **kwargs)
  File "/.venv/lib/python3.9/site-packages/pandas/core/series.py", line 2355, in idxmax
    i = self.argmax(axis, skipna, *args, **kwargs)
  File "/.venv/lib/python3.9/site-packages/pandas/core/base.py", line 647, in argmax
    return nanops.nanargmax(  # type: ignore[return-value]
  File "/.venv/lib/python3.9/site-packages/pandas/core/nanops.py", line 93, in _f
    return f(*args, **kwargs)
  File "/.venv/lib/python3.9/site-packages/pandas/core/nanops.py", line 1070, in nanargmax
    result = values.argmax(axis)  # type: ignore[var-annotated]
ValueError: attempt to get argmax of an empty sequence

我似乎也无法找到一种方法,仅将 select 不为空的组从 grouped_df 中取出,然后仅在这些组上运行idxmax() 就像我能做这样的事情一样:

group_counts = grouped_df['rel_temp'].count()
group_not_empty = (group_counts > 0)
grouped_df_no_empty_groups = grouped_df[group_not_empty]
grouped_df_no_empty_groups['rel_temp'].idxmax()

但是我似乎无法找到一种方法来做到这一点。

编辑:根据@andrej-kesely,有一种使用 apply 的方法; 然而,这非常慢,因为它使用 .apply()。 我需要能够在 20 秒内处理这些行,如果有直接(非基于应用的)方法,这应该是可能的。

任何帮助表示赞赏!

如果我对你的理解正确,你想在区间内找到最大值的索引(由pd.Grouper指定):

grouper = pd.Grouper(freq="10T")

df_out = df.groupby(grouper).apply(
    lambda x: x["rel_temp"].reset_index(drop=True).idxmax()
    if len(x)
    else np.nan
)

print(df_out)

印刷:

timestamp
2016-04-04 10:40:00    0.0
2016-04-04 10:50:00    NaN
2016-04-04 11:00:00    0.0
2016-04-04 11:10:00    NaN
2016-04-04 11:20:00    NaN
2016-04-04 11:30:00    NaN
2016-04-04 11:40:00    1.0
Freq: 10T, dtype: float64

编辑:另一个版本:

grouper = pd.Grouper(freq="10T")

t, v = [], []
for i, g in df.groupby(grouper):
    t.append(i)

    if len(g):
        v.append(max(enumerate(g["rel_temp"]), key=lambda k: k[1])[0])
    else:
        v.append(np.nan)

out = pd.DataFrame({"timestamp": t, "value": v})
print(out)

印刷:

            timestamp  value
0 2016-04-04 10:40:00    0.0
1 2016-04-04 10:50:00    NaN
2 2016-04-04 11:00:00    0.0
3 2016-04-04 11:10:00    NaN
4 2016-04-04 11:20:00    NaN
5 2016-04-04 11:30:00    NaN
6 2016-04-04 11:40:00    1.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM