给定表:
身份证 | 线 | 网站 | 日期 | 单位 | 总计 |
---|---|---|---|---|---|
1 | 十 | AAA | 2017 年 5 月 2 日 | 12 | 30 |
2 | 十 | AAA | 2017 年 5 月 3 日 | 10 | 22 |
3 | 十 | AAA | 2017 年 5 月 4 日 | 22 | 40 |
4 | 与 | AAA | 2017 年 5 月 20 日 | 15 | 44 |
5 | 与 | AAA | 2017 年 5 月 21 日 | 8 | 30 |
6 | 与 | BBB | 2017 年 5 月 22 日 | 10 | 32 |
7 | 与 | BBB | 2017 年 5 月 23 日 | 25 | 52 |
8 | 钾 | CCC | 02-Jun-2017 | 6 | 22 |
9 | 钾 | CCC | 03-Jun-2017 | 4 | 33 |
10 | 钾 | CCC | 2017 年 8 月 12 日 | 11 | 44 |
11 | 钾 | CCC | 2017 年 8 月 13 日 | 19 | 40 |
12 | 钾 | CCC | 2017 年 8 月 14 日 | 30 | 40 |
对于每一行,如果 ID,LINE,SITE 等于前一行(天)需要计算如下(最后一天)和(过去 3 天):注意,需要确保日期在 ID,LINE 的“groupby”下是连续的,站点列
身份证 | 线 | 网站 | 日期 | 单位 | 总计 | 最后一天 | 最近 3 天 |
---|---|---|---|---|---|---|---|
1 | 十 | AAA | 2017 年 5 月 2 日 | 12 | 30 | 0 | 0 |
2 | 十 | AAA | 2017 年 5 月 3 日 | 10 | 22 | 12/30 | 12/30 |
3 | 十 | AAA | 2017 年 5 月 4 日 | 22 | 40 | 10/22 | (10+12)/(30+22) |
4 | 与 | AAA | 2017 年 5 月 20 日 | 15 | 44 | 0 | 0 |
5 | 与 | AAA | 2017 年 5 月 21 日 | 8 | 30 | 15/44 | 15/44 |
6 | 与 | BBB | 2017 年 5 月 22 日 | 10 | 32 | 0 | 0 |
7 | 与 | BBB | 2017 年 5 月 23 日 | 25 | 52 | 10/32 | 10/32 |
8 | 钾 | CCC | 02-Jun-2017 | 6 | 22 | 0 | 0 |
9 | 钾 | CCC | 03-Jun-2017 | 4 | 33 | 6/22 | 6/22 |
10 | 钾 | CCC | 2017 年 8 月 12 日 | 11 | 44 | 4/33 | 0 |
11 | 钾 | CCC | 2017 年 8 月 13 日 | 19 | 40 | 11/44 | (11/44) |
12 | 钾 | CCC | 2017 年 8 月 14 日 | 30 | 40 | 19/40 | (11+19/44+40) |
在这种情况下,我通常使用 groupby 执行 for 循环:
import pandas as pd
import numpy as np
#copied your table
table = pd.read_csv('/home/fm/Desktop/stackover.csv')
table.set_index('ID', inplace = True)
table[['Last day','Last 3 days']] = np.nan
for i,r in table.groupby(['LINE' ,'SITE']):
#First subset non sequential dates
limits_interval = pd.to_datetime(r['DATE']).diff() != '1 days'
#First element is a false positive, as its impossible to calculate past days from first day
limits_interval.iloc[0]=False
ids_subset = r.index[limits_interval].to_list()
ids_subset.append(r.index[-1]+1) #to consider all values
id_start = 0
for id_end in ids_subset:
r_sub = r.loc[id_start:id_end-1, :].copy()
id_start = id_end
#move all values one day off, if the database is as in your example (1 line per day) wont have problems
r_shifted = r_sub.shift(1)
r_sub['Last day']=r_shifted['UNITS']/r_shifted['TOTAL']
aux_units_cumsum = r_shifted['UNITS'].cumsum()
aux_total_cumsum = r_shifted['TOTAL'].cumsum()
r_sub['Last 3 days'] = aux_units_cumsum/aux_total_cumsum
r_sub.fillna(0, inplace = True)
table.loc[r_sub.index,:]=r_sub.copy()
您可以创建一个函数并在 groupby 中应用,它会更清晰:将函数应用于熊猫 groupby。会更优雅。希望能帮到你,祝你好运
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句