【问题标题】:How can I average every 5 rows specific column and select last data from another column in Pandas如何平均每 5 行特定列并从 Pandas 中的另一列中选择最后一个数据
【发布时间】:2018-08-06 09:05:51
【问题描述】:

我有 pandas df,比如 100 行 4 列。我想每 5 行计算特定列(“值”)中的平均值,并选择另一列(“日期”)的最后一个数据(第五个)以保留在新数据框中。

我的数据框看起来像这样:

>>df
       DateTime     Product     Location       Value
0    12-07-2018           A           S1       1.313
1    12-07-2018           B           S1       3.089
2    12-07-2018           C           S1       1.890
3    12-07-2018           D           S1       3.136
4**  12-07-2018           E           S1       3.258
5    13-07-2018           F           S1       3.113
6    13-07-2018           G           S1       2.651
7    13-07-2018           H           S1       2.135
8    13-07-2018           I           S1       1.555
9**  14-07-2018           J           S1       2.009
10   14-07-2018           K           S1       1.757
11   14-07-2018           L           S1       1.808
12   14-07-2018           M           S1       1.511
13   15-07-2018           N           S1       2.265
14** 15-07-2018           O           S1       2.356
15   15-07-2018           P           S1       2.950
16   15-07-2018           Q           S1       3.300

现在我可以通过这段代码平均每 5 行:

> new_df = df.groupby(df.index // 5).agg({'DateTime':'last', 'Value':'mean'})

这段代码的结果:

>> new_df
     DateTime        Value
0  12-07-2018       2.5372
1  14-07-2018       2.2926
2  15-07-2018       1.9394
3  15-07-2018       3.1250

但最后 2 行的平均值相同。 (2.950+3.300)/2 = 3.1250。如果它有 1,2,3,4 行,它将平均行数。

我只想平均 5 行。如果它没有 5 行,则不要平均并发送到 new_df

我该怎么做?

注意:为了便于观察,我每 5 行添加 **。

【问题讨论】:

    标签: python python-2.7 pandas dataframe


    【解决方案1】:

    据我所知,您的请求相当于在聚合之前将 df 截断为可被 5 整除的长度。您可以即时使用切片:

    new_df = df.groupby(df[:(len(df)//5)*5].index // 5).agg({'DateTime':'last', 'Value':'mean'})
    

    【讨论】:

    • 我使用你的代码,但 VSC 调用 ValueError : Grouper 和 axis 必须是相同的长度。我尝试将代码更改为新代码是 new_df = df[:(len(df)//5)*5].groupby(df[:(len(df)//5)*5].index // 5) .agg({'DateTime':'last', 'Value':'mean'})。它可以工作!非常感谢。
    【解决方案2】:

    用途:

    i = df.index // 5
    #compare by last value
    mask = i == i[-1]
    #length of last group
    no = mask.sum()
    
    #filter only if last group less as 5
    no = mask.sum()
    if no < 5:
        df = df[~mask]
    

    另一个想法:

    s = pd.Series(df.index // 5)
    df = df[s.groupby(s).transform('count') == 5]
    

    new_df = df.groupby(df.index // 5).agg({'DateTime':'last', 'Value':'mean'})
    print (new_df)
         DateTime   Value
    0  12-07-2018  2.5372
    1  14-07-2018  2.2926
    2  15-07-2018  1.9394
    

    【讨论】:

    • 我忘了描述 15 16 的 df 行,不要发送到 new_df(仅 5 行)。我会编辑我的帖子。对不起先生。
    • @kanpiseksasuk - 这是不同的;)检查编辑的答案。
    • 您的解决方案对我有用!非常感谢。非常感谢您的帮助。
    • 我可以使用聚合来选择 ({'DateTime':'last', 'Value':'mean'}, 'Product':'all') 以显示产品 A、B、C、 D,E // F,G,H,I,J,每 5 行分组时?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    • 2022-08-20
    相关资源
    最近更新 更多