python - 两个日期时间之间的平均值;如果是 NaN,则获取最后一个非 NaN 值

标签 python pandas dataframe

昨天问了this问题(有一些很好的答案)非常相似,但与我现在遇到的问题略有不同。说我有以下 pd.DataFrame ( dict ):

    eff_timestamp       val         id  begin_timestamp     end_timestamp
0   2021-01-01 00:00:00 -0.710230   1   2021-01-01 02:00:00 2021-01-01 05:30:00
1   2021-01-01 01:00:00 0.121464    1   2021-01-01 02:00:00 2021-01-01 05:30:00
2   2021-01-01 02:00:00 -0.156328   1   2021-01-01 02:00:00 2021-01-01 05:30:00
3   2021-01-01 03:00:00 0.788685    1   2021-01-01 02:00:00 2021-01-01 05:30:00
4   2021-01-01 04:00:00 0.505210    1   2021-01-01 02:00:00 2021-01-01 05:30:00
5   2021-01-01 05:00:00 -0.738344   1   2021-01-01 02:00:00 2021-01-01 05:30:00
6   2021-01-01 06:00:00 0.266910    1   2021-01-01 02:00:00 2021-01-01 05:30:00
7   2021-01-01 07:00:00 -0.587401   1   2021-01-01 02:00:00 2021-01-01 05:30:00
8   2021-01-02 00:00:00 -0.160692   2   2021-01-02 12:00:00 2021-01-02 15:30:00
9   2021-01-02 01:00:00 0.306354    2   2021-01-02 12:00:00 2021-01-02 15:30:00
10  2021-01-02 02:00:00 NaN         2   2021-01-02 12:00:00 2021-01-02 15:30:00
11  2021-01-02 03:00:00 NaN         2   2021-01-02 12:00:00 2021-01-02 15:30:00
12  2021-01-02 04:00:00 NaN         2   2021-01-02 12:00:00 2021-01-02 15:30:00
13  2021-01-02 05:00:00 NaN         2   2021-01-02 12:00:00 2021-01-02 15:30:00
14  2021-01-02 06:00:00 NaN         2   2021-01-02 12:00:00 2021-01-02 15:30:00
15  2021-01-02 07:00:00 -0.349705   2   2021-01-02 12:00:00 2021-01-02 15:30:00
我想得到 val 的平均值对于每个唯一的 id,对于那些 val位于 begin_timestamp 之间和 end_timestamp .如果没有满足该条件的行,我想获取该 id 的最后一个值。在那个时期之前。请注意,在此示例中, id=2 没有满足条件的行。以前我可以切片数据,所以我只保留 begin 和 end_timestamp 之间的行,然后使用 groupby。我上一篇文章中的解决方案然后替换了 groupby 对象中的 NaN 值。但是,在上面的示例中, id=2 根本没有满足条件的行,因此没有创建可以替换的 NaN 值。因此,如果我根据上述标准对数据进行切片:
sliced = df[(df.eff_timestamp > df.begin_timestamp) & (df.eff_timestamp < df.end_timestamp)]
sliced
>>>     

    eff_timestamp       val         id  begin_timestamp     end_timestamp
3   2021-01-01 03:00:00 0.788685    1   2021-01-01 02:00:00 2021-01-01 05:30:00
4   2021-01-01 04:00:00 0.505210    1   2021-01-01 02:00:00 2021-01-01 05:30:00
5   2021-01-01 05:00:00 -0.738344   1   2021-01-01 02:00:00 2021-01-01 05:30:00

sliced.groupby('id').val.mean()
>>>
id
1    0.185184
Name: val, dtype: float64
这个结果只包括 id=1 的平均值,但没有 id=2 的值。我将如何而不是平均值包含 id=2 的最后一个可用值,即 -0.349705?

最佳答案

创建临时列 between_time .然后Groupby id列,然后在 apply添加条件 -> If 对于特定 id范围内是否有任何值?如果是,取平均值,否则取 last_valid_index 处的值.

result = (
    df.assign(
        between_time=(df.eff_timestamp > df.begin_timestamp) & (df.eff_timestamp < df.end_timestamp))
    .groupby('id')
    .apply(
        lambda x: x.loc[x['between_time']]['val'].mean()
        if any(x['between_time'].values)
        else
        x.loc[x['val'].last_valid_index()]['val']
    )
)
输出:
id
1    0.185184
2   -0.349705
dtype: float64

关于python - 两个日期时间之间的平均值;如果是 NaN,则获取最后一个非 NaN 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67875106/

相关文章:

python - 如何将 CMS 页面从开发站点复制到实时站点?

python - 如何快速使用格式打印列表?

python - 将 NumPy 矩阵的不同值部分的上三角和下三角提取到 2 列 pandas

python - 根据匹配列映射多个数据帧

r - 合并具有不同行数和不同列的数据框

python - 我在使用 Python 的 Power Set 中陷入递归困境

python - 如何在符合给定条件的python列表中获取字典

python - 在 Pandas DataFrame 上的日期列上使用 numpy is_busday 函数

python - 给定两个时间戳,我如何根据 "business minutes"返回增量

python - 在没有 for 循环的情况下在数据框中“过采样”笛卡尔数据?