iT邦幫忙

0

Python 搭配條件 計算欄位累計值

KL 2021-10-13 10:01:46397 瀏覽

資料範例:
https://ithelp.ithome.com.tw/upload/images/20211013/20139417Oxo5zKQ4BQ.png

期望輸出:
https://ithelp.ithome.com.tw/upload/images/20211013/20139417LoED0KS10R.png

解說:

  1. 欲使用Python pandas新增 Total_Count欄位,根據每日Count_Record累計次數與是否在同一個Site
  2. 舉例來說,card C1 從10/12-10/16都在Site A沒換過場地,故Total_Count欄位直接累計當日與前日的差額。
  3. 而card C2 在10/13從Site B轉換到Site A,10/13的Count_Record會先"歸零"並在紀錄當日在Site A的增額(即為2),而Toal_Count則增加為13 (11+2)。card C2 10/14-10/15都在Site A,故Total_Count只是直接累計當日與前日的差額。而後10/16又換到Site B,故"歸零"再紀錄當日增額(即為4),而Toal_Count則最後增加為28 (24+4)。
  4. 若搭配下表每日增額的欄位可能比較好理解:
    https://ithelp.ithome.com.tw/upload/images/20211013/20139417i1DTTChkul.png

以下是資料程式碼,想請問怎麼寫出用if 判斷當日是否與前日同Site,再做Total_Count的累計,謝謝!

import pandas as pd
df1 = pd.DataFrame(columns=['site', 'card', 'date', 'count_record'],
          data=[['A', 'C1', '12-Oct', 5], 
                ['A', 'C1', '13-Oct', 10], 
                ['A', 'C1', '14-Oct', 18],
                ['A', 'C1', '15-Oct', 21], 
                ['A', 'C1', '16-Oct', 29],
                ['B', 'C2', '12-Oct', 11],
                ['A', 'C2', '13-Oct', 2],
                ['A', 'C2', '14-Oct', 7],
                ['A', 'C2', '15-Oct', 13],
                ['B', 'C2', '16-Oct', 4]])

1 個回答

2
frank_huang
iT邦新手 5 級 ‧ 2021-10-13 16:13:42
最佳解答

可以把舊值存起來進行比較。
PS: 沒安裝環境就沒測試,有誤再請修正。

total = 0;
preCard = '';
preSite = '';
preCount = 0;
for row in df1:
	if(card != preCard){
		total  = 0;
		preCount = 0;
		preSite = '';
	}
	if(site == preSite) {
		total += (count - preCount);
	} else {
		total += count;
	}
	df1[Total_Count] = total;
	
	preCount = count;
	preSite = site;
	preCard = card;
KL iT邦新手 5 級 ‧ 2021-10-14 11:20:21 檢舉

謝謝提供想法,以下是我的code解決了這個問題!

import pandas as pd
df1 = pd.DataFrame(columns=['site', 'card', 'date', 'count_record'],
          data=[['A', 'C1', '12-Oct', 5], 
                ['A', 'C1', '13-Oct', 10], 
                ['A', 'C1', '14-Oct', 18],
                ['A', 'C1', '15-Oct', 21], 
                ['A', 'C1', '16-Oct', 29],
                ['B', 'C2', '12-Oct', 11],
                ['A', 'C2', '13-Oct', 2],
                ['A', 'C2', '14-Oct', 7],
                ['A', 'C2', '15-Oct', 13],
                ['B', 'C2', '16-Oct', 4]])

def calc_total_count(df2: pd.DataFrame) -> pd.Series:
    total = 0
    pre_count = 0
    pre_site = ''
    lst = []
    for c, s in zip(df2['count_record'], df2['site']):
        if s == pre_site:
            total += (c - pre_count)
        else:
            total += c

        pre_count = c
        pre_site = s
        lst.append(total)
    return pd.Series(lst, index=df2.index, name='Total_Count')


df3 = pd.concat([
    df1, df1.sort_values('date').groupby('card').apply(calc_total_count).droplevel(0)
], axis=1)

我要發表回答

立即登入回答