繁体   English   中英

熊猫在时间序列中计数零

[英]Pandas Count zeros in time series

我有一个每日时间序列 [1980 年至今],我需要在其中检查每个每日时间步长是否为零并系统地删除记录。 我最终想对这个解决方案进行矢量化,这样我就可以在继续我的分析之前对这些操作进行预处理。 如果我有数据框df

         date               name  elev_exact      swe
0  1990-10-30   COTTONWOOD_CREEK    2337.816  0.01524
1  1990-10-30    EMIGRANT_SUMMIT    2252.472  0.00000
2  1990-10-30     PHILLIPS_BENCH    2499.360  0.05334
3  1990-10-30    PINE_CREEK_PASS    2048.256  0.00000
4  1990-10-30  SALT_RIVER_SUMMIT    2328.672  0.00000
5  1990-10-30      SEDGWICK_PEAK    2392.680  0.00000
6  1990-10-30          SHEEP_MTN    2026.920  0.00000
7  1990-10-30  SLUG_CREEK_DIVIDE    2202.180  0.00000
8  1990-10-30       SOMSEN_RANCH    2072.640  0.00000
9  1990-10-30   WILDHORSE_DIVIDE    1978.152  0.00000
10 1990-10-30       WILLOW_CREEK    2462.784  0.01778
11 1991-03-15   COTTONWOOD_CREEK    2337.816  0.41910
12 1991-03-15    EMIGRANT_SUMMIT    2252.472  0.42418
13 1991-03-15     PHILLIPS_BENCH    2499.360  0.52832
14 1991-03-15    PINE_CREEK_PASS    2048.256  0.32258
15 1991-03-15  SALT_RIVER_SUMMIT    2328.672  0.23876
16 1991-03-15      SEDGWICK_PEAK    2392.680  0.39878
17 1991-03-15          SHEEP_MTN    2026.920  0.31242
18 1991-03-15  SLUG_CREEK_DIVIDE    2202.180  0.29464
19 1991-03-15       SOMSEN_RANCH    2072.640  0.29972
20 1991-03-15   WILDHORSE_DIVIDE    1978.152  0.35052
21 1991-03-15       WILLOW_CREEK    2462.784  0.60706
22 1991-10-25   COTTONWOOD_CREEK    2337.816  0.01270
23 1991-10-25    EMIGRANT_SUMMIT    2252.472  0.01016
24 1991-10-25     PHILLIPS_BENCH    2499.360  0.02286
25 1991-10-25    PINE_CREEK_PASS    2048.256  0.00508
26 1991-10-25  SALT_RIVER_SUMMIT    2328.672  0.01016
27 1991-10-25      SEDGWICK_PEAK    2392.680  0.00254
28 1991-10-25          SHEEP_MTN    2026.920  0.00000
29 1991-10-25  SLUG_CREEK_DIVIDE    2202.180  0.00762
30 1991-10-25       SOMSEN_RANCH    2072.640  0.00000
31 1991-10-25   WILDHORSE_DIVIDE    1978.152  0.00508
32 1991-10-25       WILLOW_CREEK    2462.784  0.02032

问题是我想找到超过一个零swe测量值的日子,并且只保留最大elev_exact的观察结果。 然后我需要将所需的零记录合并回df

这是一个可以实现我想要的 groupby 循环:

result = pd.DataFrame()
for name, group in df.groupby('date'):

    non_zero = group.where(group.swe >0).dropna()

    if not group.equals(non_zero):
        zeros = group.where(group.swe == 0).dropna() 
        zero_kept = zeros.loc[zeros.elev_exact.idxmax()]
        out = non_zero.append(zero_kept)
        out = out[out.elev_exact >= zero_kept.elev_exact]
        result = pd.concat([result, out])
    else:
        result = pd.concat([result, non_zero])

我不介意使用groupby但我想更有条理地使用它,所以我没有内部if-else循环。

这是我对这个问题的思考方式

  1. 对于每天的每个时间步,我想找到有多个零测量的地方
zero_count = df.groupby('date').apply(lambda x: np.count_nonzero(x==0))
zero_count = zero_count.where(zero_count >1).dropna()
  1. 使用zero_count > 1分隔日期
zero_fix = zero_count.where(zero_count >1).dropna()
  1. 使用多个零查找每天的最大海拔
fixes = df[df.date.isin(zero_fix.index)].dropna()
fixes = fixes.loc[fixes[fixes.swe==0].groupby('date')['elev_exact'].idxmax().to_list()]
  1. 将找到的高程阈值应用回df
df.loc[:,'threshold'] = df.date.map(lu_dict)
df = df.replace(np.nan, 0)
df = df[df.elev_exact >= df.threshold].drop('threshold', axis=1)

这也有效,但 lambda 函数是第 1 步非常慢。 还有另一种计算零的方法吗?

预期输出:

          date               name  elev_exact      swe
2   1990-10-30     PHILLIPS_BENCH    2499.360  0.05334
5   1990-10-30      SEDGWICK_PEAK    2392.680  0.00000
10  1990-10-30       WILLOW_CREEK    2462.784  0.01778
11  1991-03-15   COTTONWOOD_CREEK    2337.816  0.41910
12  1991-03-15    EMIGRANT_SUMMIT    2252.472  0.42418
13  1991-03-15     PHILLIPS_BENCH    2499.360  0.52832
14  1991-03-15    PINE_CREEK_PASS    2048.256  0.32258
15  1991-03-15  SALT_RIVER_SUMMIT    2328.672  0.23876
16  1991-03-15      SEDGWICK_PEAK    2392.680  0.39878
17  1991-03-15          SHEEP_MTN    2026.920  0.31242
18  1991-03-15  SLUG_CREEK_DIVIDE    2202.180  0.29464
19  1991-03-15       SOMSEN_RANCH    2072.640  0.29972
20  1991-03-15   WILDHORSE_DIVIDE    1978.152  0.35052
21  1991-03-15       WILLOW_CREEK    2462.784  0.60706
22  1991-10-25   COTTONWOOD_CREEK    2337.816  0.01270
23  1991-10-25    EMIGRANT_SUMMIT    2252.472  0.01016
24  1991-10-25     PHILLIPS_BENCH    2499.360  0.02286
26  1991-10-25  SALT_RIVER_SUMMIT    2328.672  0.01016
27  1991-10-25      SEDGWICK_PEAK    2392.680  0.00254
29  1991-10-25  SLUG_CREEK_DIVIDE    2202.180  0.00762
30  1991-10-25       SOMSEN_RANCH    2072.640  0.00000
32  1991-10-25       WILLOW_CREEK    2462.784  0.02032

您可以尝试这样做,将数据帧拆分为非零和零,然后按最高 elev_exact 对零数据帧进行排序,并在日期列上使用带有子集的drop_duplicates 最后,使用pd.concat将数据帧重新连接在一起并排序:

df_nonzeroes = df[df['swe'].ne(0)]
df_zeroes = df[df['swe'].eq(0)].sort_values('elev_exact', ascending=False).drop_duplicates(subset=['date'])

df_out = pd.concat([df_nonzeroes, df_zeroes]).sort_index()
print(df_out)

输出:

          date               name  elev_exact      swe
0   1990-10-30   COTTONWOOD_CREEK    2337.816  0.01524
2   1990-10-30     PHILLIPS_BENCH    2499.360  0.05334
5   1990-10-30      SEDGWICK_PEAK    2392.680  0.00000
10  1990-10-30       WILLOW_CREEK    2462.784  0.01778
11  1991-03-15   COTTONWOOD_CREEK    2337.816  0.41910
12  1991-03-15    EMIGRANT_SUMMIT    2252.472  0.42418
13  1991-03-15     PHILLIPS_BENCH    2499.360  0.52832
14  1991-03-15    PINE_CREEK_PASS    2048.256  0.32258
15  1991-03-15  SALT_RIVER_SUMMIT    2328.672  0.23876
16  1991-03-15      SEDGWICK_PEAK    2392.680  0.39878
17  1991-03-15          SHEEP_MTN    2026.920  0.31242
18  1991-03-15  SLUG_CREEK_DIVIDE    2202.180  0.29464
19  1991-03-15       SOMSEN_RANCH    2072.640  0.29972
20  1991-03-15   WILDHORSE_DIVIDE    1978.152  0.35052
21  1991-03-15       WILLOW_CREEK    2462.784  0.60706
22  1991-10-25   COTTONWOOD_CREEK    2337.816  0.01270
23  1991-10-25    EMIGRANT_SUMMIT    2252.472  0.01016
24  1991-10-25     PHILLIPS_BENCH    2499.360  0.02286
25  1991-10-25    PINE_CREEK_PASS    2048.256  0.00508
26  1991-10-25  SALT_RIVER_SUMMIT    2328.672  0.01016
27  1991-10-25      SEDGWICK_PEAK    2392.680  0.00254
29  1991-10-25  SLUG_CREEK_DIVIDE    2202.180  0.00762
30  1991-10-25       SOMSEN_RANCH    2072.640  0.00000
31  1991-10-25   WILDHORSE_DIVIDE    1978.152  0.00508
32  1991-10-25       WILLOW_CREEK    2462.784  0.02032

暂无
暂无

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

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