Python Pandas Dataframe-每两周计算值的总和

时间:2018-06-29 11:59:20

标签: python pandas

我有一个数据框,其值如下-

               Amount  Product  DocDate
0              1099.0   1100 2018-01-02
1              1234.0   1100 2018-01-04
2              1000.0   1100 2018-01-06
3              8000.0   1100 2018-01-28
4              3000.0   1100 2018-02-09
5              4500.0   1100 2018-02-20

我需要计算每个两周结束时计算的金额字段的总和。

示例:

Product Amount FortNight
1100    3333.0  Jan 1st Fortnight (this could be date format too!!)
1100    3000.0  Feb 2nd Fortnight
1100    4500.0  Feb 1st Fortnight

如果它不涉及循环,那就太好了(因为我也有产品循环) 我尝试将周和月分开(分组)并进行计算,但是由于它在数据框中是一列,因此无法获得预期的结果。

先谢谢了。感谢帮助。

2 个答案:

答案 0 :(得分:2)

首先,我有点担心,因为您说过您正在对熊猫使用循环……您永远不要对熊猫使用循环,因为熊猫不是专门为循环而设计的,循环极其缓慢且无效。在某些非常罕见的情况下,您无法避免它,但是即使如此,仍有一些选项可以更好地对其进行优化。

要回答您的问题,首先需要将DocDate转换为日期时间格式:

from datetime import datetime
df.DocDate = df.DocDate.apply(lambda d: datetime.strptime(d, %Y-%m-%d))

然后,您可以使用datetimeIndex.resample函数,其功能与groupby完全相同,但可以按时间限制对数据进行分组:

df = df.set_index('DocDate').resample('2W').Amount.sum()

resample('2W')在这里是指按2周为一组。

答案 1 :(得分:1)

需要:

#if necessary convert column to datetime
df['DocDate'] = pd.to_datetime(df['DocDate'])
#generate Fortnight https://stackoverflow.com/a/34428879
s =  np.where(df['DocDate'].dt.day < 15, '1st Fortnight', '2nd Fortnight')
#create new column
df['FortNight'] = df['DocDate'].dt.strftime('%b ') + s
#aggregate sum
df = df.groupby(['Product','FortNight'], as_index=False, sort=False)['Amount'].sum()
print (df)
   Product          FortNight  Amount
0     1100  Jan 1st Fortnight  3333.0
1     1100  Jan 2nd Fortnight  8000.0
2     1100  Feb 1st Fortnight  3000.0
3     1100  Feb 2nd Fortnight  4500.0

如果输出中需要日期时间:

s =  np.where(df['DocDate'].dt.day < 15, '-01', '-15')
df['FortNight'] = pd.to_datetime(df['DocDate'].dt.strftime('%Y-%m') + s)

df = df.groupby(['Product','FortNight'], as_index=False, sort=False)['Amount'].sum()
print (df)
   Product  FortNight  Amount
0     1100 2018-01-01  3333.0
1     1100 2018-01-15  8000.0
2     1100 2018-02-01  3000.0
3     1100 2018-02-15  4500.0