计算pandas中列中第n个元素的平均值

时间:2017-07-04 11:06:37

标签: python pandas

我有以下数据框:

             df1
index   year   week   a     b     c
 -10    2017    10   45    26    19
  -9    2017    11   37    23    14
  -8    2017    12   21    66    19
  -7    2017    13   47    36    92
  -6    2017    14   82    65    18
  -5    2017    15   68    68    19
  -4    2017    16   30    95    24
  -3    2017    17   21    15    94
  -2    2017    18   67    30    16
  -1    2017    19   10    13    13
   0    2017    20   26    22    18
   1    2017    21   NaN   NaN   NaN
   2    2017    22   NaN   NaN   NaN
   3    2017    23   NaN   NaN   NaN
   4    2017    24   NaN   NaN   NaN
   ...
   53   2018    20   NaN   NaN   NaN

我需要为每个空单元格计算列中前一个第n个值的平均值,并将此值写入单元格。 n等于零和向上的索引数。例如,对于a列中的第一个空单元格,我必须计算索引0-10之间的平均值。然后是1-9之间的下一个单元格,依此类推。列abc也是如此。计算总是从index = 1

开始

问题是abc等列数可能不同。但我知道这些列将始终位于列week之后。是否可以将这些计算应用于不确定数量的列,但是如果已知这些列将位于列week之后?

我努力寻找任何东西,但我找不到合适的东西。

UPD :如果这有帮助,index = 0及以下的最大行数将为53

2 个答案:

答案 0 :(得分:2)

可以这样做:

n = 11 # in the example of your explanation
df = df1.loc[range(1,df1.index[-1]+1)] # select rows from index 1 above

df应如下所示:

       year  week   a   b   c
index                        
1      2017    21 NaN NaN NaN
2      2017    22 NaN NaN NaN
3      2017    23 NaN NaN NaN
4      2017    24 NaN NaN NaN

然后你:

for s in list(df.index): # iterate through rows with nan values
    for i in range(2,df.columns.size): # iterate through different cols ('a','b','c' or more)
        df1.loc[s,df.columns[i]] = df1.loc[range(s-n,s),df.columns[i]].sum()/n
print(df1)

请注意,在这种情况下,我按照了您的示例,并认为year始终是第一列,week总是第二列,以便选择week和{{1之后的所有列是......以及索引

输出:

index

答案 1 :(得分:1)

你可以通过玩熊猫和numpy来做一些这样的事情。假设你知道week列的索引是什么(即使你没有,一个简单的搜索会得到你的索引),例如,week列是第3个你可以做类似

的事情
import numpy as np
import pandas as pd
#data is your dataframe name
column_list = list(data.columns.values)[3:]
for column_name in column_list :
    column = data[column_name].values
    #converted pandas series to numpy series
    for index in xrange(0,column.shape[0]):
        #iterating over entries in the column
        if np.isnan(column[index]):
            column[index] = np.nanmean(column.take(range(index-10,index+1),mode='wrap'))

这是一个糟糕的未经验证的解决方案,但应该可以正常工作。它将用前面的10个条目替换所有NaN条目。如果你只想要前面的10个没有一个环绕,你只需要将第一个n取为n小于10 ,如 new_df[index] = np.nanmean(new_df[max(0,index-10):index+1])

希望这有帮助!