我有一个像下面这样的pandas Dataframe:
import pandas as pd
df = pd.DataFrame({'name': ['AAA','BBB','CCC'],
'2017-01-06': ['3','3','4'],
'2017-01-13': ['2','1','5'],
'2017-01-20': ['1','3','4'],
'2017-01-27': ['8','3','5'],
'average_count': ['4','3','5']})
df = df.reindex_axis(['name','2017-01-06','2017-01-13','2017-01-20','2017-01-27','average_count'], axis=1)
print df
name 2017-01-06 2017-01-13 2017-01-20 2017-01-27 average_count
0 AAA 3 2 1 8 4
1 BBB 3 1 3 3 3
2 CCC 4 5 4 5 5
我想要一个包含四列的输出数据框:名称,日期,计数, average_count 。< / p>
如果是第一周的月份,那么平均计数需要计算(第一周的数量)/ 1。
第2周,(第一周的数量+第一周的数量)/ 2。
第3周,(第一周的数量+第二周的数量+第三周的数量)/ 3。
第4周,(第一周的数量+第二周的数量+第三周的数量+第四周的数量)/ 4。
在一个月内可以使用最多五周(需要处理五周的情况)。
编辑1:平均计数值计算
此平均计数值被截断,如果值<= 2.49,即2和值&gt; = 2.50,即3。
输出数据框如下所示:
name date count average_count
0 AAA 2017-01-06 3 3
1 AAA 2017-01-13 2 2
3 AAA 2017-01-20 1 2
3 AAA 2017-01-27 8 4
4 BBB 2017-01-06 3 3
5 BBB 2017-01-13 1 2
6 BBB 2017-01-20 3 3
7 BBB 2017-01-27 3 3
8 CCC 2017-01-06 4 4
9 CCC 2017-01-13 5 5
10 CCC 2017-01-20 4 3
11 CCC 2017-01-27 5 5
答案 0 :(得分:3)
您可以堆叠值和reset_index以获得4列的数据帧,即
def round_next(x):
if x%1 == 0.5:
return x+0.5
else :
return np.round(x)
ndf = df.set_index(['name','average_count']).stack().reset_index().rename(columns = {'level_2':'date',0:'count'})
ndf['date'] = pd.to_datetime(ndf['date'])
ndf['count'] =ndf['count'].astype(int) # Since they are in string format
#Thank you @Zero. Since they are dates appearing to be taken weekly once groupby cumcount() + 1 will do that work.
#Incase you have missing weeks then I would suggest dt.week i.e ndf.groupby('name')['date'].dt.week
ndf['average_count'] = (ndf.groupby('name')['count'].cumsum()/(ndf.groupby('name')['count'].cumcount()+1)).apply(round_next)
name average_count date count 0 AAA 3.0 2017-01-06 3 1 AAA 3.0 2017-01-13 2 2 AAA 2.0 2017-01-20 1 3 AAA 4.0 2017-01-27 8 4 BBB 3.0 2017-01-06 3 5 BBB 2.0 2017-01-13 1 6 BBB 2.0 2017-01-20 3 7 BBB 3.0 2017-01-27 3 8 CCC 4.0 2017-01-06 4 9 CCC 5.0 2017-01-13 5 10 CCC 4.0 2017-01-20 4 11 CCC 5.0 2017-01-27 5
答案 1 :(得分:2)
使用df.melt
,df.sort_values
和df.reset_index
作为第一位。
df2 = df.iloc[:, :-1].melt('name', var_name=['date'], value_name='count')\
.sort_values('name').reset_index(drop=True)
# cleaning up OP's data
df2['count'] = pd.to_numeric(df2['count'])
df2['date'] = pd.to_datetime(df2.date)
df2
name date count
0 AAA 2017-01-06 3
1 AAA 2017-01-13 2
2 AAA 2017-01-20 1
3 AAA 2017-01-27 8
4 BBB 2017-01-06 3
5 BBB 2017-01-13 1
6 BBB 2017-01-20 3
7 BBB 2017-01-27 3
8 CCC 2017-01-06 4
9 CCC 2017-01-13 5
10 CCC 2017-01-20 4
11 CCC 2017-01-27 5
现在,您需要groupby
name
,获取cumsum
count
并除以周数,您可以通过{{1}访问}。
dt.week