pandas Groupby使用序列并计算和

wnrlj8wa  于 2023-09-29  发布在  其他
关注(0)|答案(2)|浏览(104)

我有一个这样的数据框

Name COST      Timestamp
0   c   8   2023-09-20 15:14:46
1   a   8   2023-09-20 15:14:48
2   c   9   2023-09-20 15:14:55
3   b   10  2023-09-20 15:15:00
4   c   4   2023-09-20 15:15:02
5   a   9   2023-09-20 15:15:04
6   b   3   2023-09-20 15:15:12
7   a   3   2023-09-20 15:15:17
8   c   6   2023-09-20 15:15:20
9   c   6   2023-09-20 15:15:29

我想要的是创建一个新的dataframe。它将查找a,B,c的序列(顺序在这里无关紧要),sum_cost是a,b,c的成本之和,它的time_stamp将是a,b,c的最后一个time_stamp。如果有多个相同名称的条目,比如B,c,c,b,b,a,则取最后一个c,然后取最后一个b和a。

  • 一个详细的例子 *:

输出应该来自给定的 Dataframe ,将被构造成这样,对于第一个,它将采用索引1的‘a’、索引2的‘c’(因为这在索引0的‘c’之后)和索引3的‘b’,对于该组,sum_cost将是27,并且timestamp将是2023-09- 2000:14:26,它是索引3的‘b’,因为它对于该组是最后一个。下一组将采用索引4的'c',索引5的'a'和索引6的'B',sum_cost将为16,timestamp将为2023-09-20 00:06:51,这是索引6的'b',因为它是这个序列的最后一个。
输出将如下所示,

sum_cost   Timestamp
0   27  2023-09-20 15:15:00
1   16  2023-09-20 15:15:12

请帮我拿这个。谢谢你,谢谢!

yi0zb3m4

yi0zb3m41#

你需要构建一个自定义的分组器,为此需要一个循环,这里使用一个自定义函数:

def group_consecutive(s, target):
    out = []
    i = 0

    g = 1
    while i < len(s)-len(target)+1:
        if target == set(s.iloc[i:i+len(target)]):
            out.extend([g]*len(target))
            g += 1
            i += len(target)
        else:
            out.append(0)
            i += 1
    out.extend([0]*(len(target)-1))

    return pd.Series(out, index=s.index)

group = group_consecutive(df['Name'], {'a', 'b', 'c'})

out = df[group>0].groupby(group).agg({'COST': 'sum', 'Timestamp': 'last'})

输出量:

COST            Timestamp
1    27  2023-09-20 15:15:00
2    16  2023-09-20 15:15:12

中间体组:

Name  COST            Timestamp  group
0    c     8  2023-09-20 15:14:46      0
1    a     8  2023-09-20 15:14:48      1
2    c     9  2023-09-20 15:14:55      1
3    b    10  2023-09-20 15:15:00      1
4    c     4  2023-09-20 15:15:02      2
5    a     9  2023-09-20 15:15:04      2
6    b     3  2023-09-20 15:15:12      2
7    a     3  2023-09-20 15:15:17      0
8    c     6  2023-09-20 15:15:20      0
9    c     6  2023-09-20 15:15:29      0
ctehm74n

ctehm74n2#

你可以试试这个代码你需要改变你的数据框的路径

from datetime import datetime 
import pandas as pd

df =pd.read_csv("df.csv")
a_tmp= b_tmp= c_tmp= max_tmp = datetime(1998, 5, 3)
a_value= b_value= c_value = None
df2 = pd.DataFrame(columns=['sum_cost','timestamp'])

for row in range(len(df)):
    if df['Name'][row] == 'a' and datetime.strptime(df['Timestamp'][row],"%Y-%m-%d %H:%M:%S")> a_tmp:
        a_value = df['COST'][row]
        a_tmp = datetime.strptime(df['Timestamp'][row],"%Y-%m-%d %H:%M:%S")
        if a_tmp > max_tmp:
            max_tmp = a_tmp
    elif  df['Name'][row] == 'b' and datetime.strptime(df['Timestamp'][row],"%Y-%m-%d %H:%M:%S")> b_tmp:
        b_value = df['COST'][row]
        b_tmp = datetime.strptime(df['Timestamp'][row],"%Y-%m-%d %H:%M:%S")
        if b_tmp > max_tmp:
            max_tmp = b_tmp
    elif df['Name'][row] == 'c' and datetime.strptime(df['Timestamp'][row],"%Y-%m-%d %H:%M:%S")> c_tmp:
        c_value = df['COST'][row]
        c_tmp = datetime.strptime(df['Timestamp'][row],"%Y-%m-%d %H:%M:%S")
        if c_tmp > max_tmp:
            max_tmp = c_tmp
    if a_value is not None and b_value is not None and c_value is not None:
        sum_of_value =  a_value+ b_value + c_value
        df2.loc[len(df2.index)] =[sum_of_value,max_tmp]
        a_tmp= b_tmp= c_tmp= max_tmp = datetime(1998, 5, 3)
        a_value =  b_value =  c_value = None
        
df2

相关问题