融化并找到熊猫数据框中的平均数

时间:2017-09-18 10:04:38

标签: python pandas dataframe

我有一个像下面这样的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>

  • 名称列包含上述数据框中的名称。
  • 日期列包含每个单独名称的四个不同日期。
  • count 列包含相应日期的计数值。
  • average_count 包含四种不同的平均计数值。

如果是第一周的月份,那么平均计数需要计算(第一周的数量)/ 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

2 个答案:

答案 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.meltdf.sort_valuesdf.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