Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建动态范围并计算平均值_Python_Pandas_Dataframe_Mean - Fatal编程技术网

Python 创建动态范围并计算平均值

Python 创建动态范围并计算平均值,python,pandas,dataframe,mean,Python,Pandas,Dataframe,Mean,我想使用动态范围创建一个附加列,其中包含基于A列的平均值 import numpy as np import pandas as pd test = {'A' : [100, 120, 70, 300, 190, 70, 300, 190, 70], 'B' : [80, 50, 64, 288, 172, 64, 288, 172, 64], 'C' : ['NO', 'NO', 'YES', 'NO', 'YES', 'YES', 'NO', 'YE

我想使用动态范围创建一个附加列,其中包含基于A列的平均值

import numpy as np
import pandas as pd
    
test = {'A' : [100, 120, 70, 300, 190, 70, 300, 190, 70],
        'B' : [80, 50, 64, 288, 172, 64, 288, 172, 64],
        'C' : ['NO', 'NO', 'YES', 'NO', 'YES', 'YES', 'NO', 'YES', 'YES'],
        'D' : [0, 1, 0, 3, 2, 2, 3, 1, 4] }

df = pd.DataFrame(data=test)

     A      B      C      D    
0   100    80     NO      0
1   120    50     NO      1
2    70    64    YES      0
3   300   288     NO      3
4   190   172    YES      2
5    70    64    YES      2
6   300   288     NO      3
7   190   172    YES      1
8    70    64    YES      4
当列
C
中的项为
YES
时,使用列
D
中的值作为起始行索引,使用当前行
-1
的行索引作为最高行索引,从列
A
中的动态范围中获取平均值

以下是我寻求实现的结果

     A      B      C      D    Dyn_Ave    
0   100    80     NO      0     NaN
1   120    50     NO      1     NaN
2    70    64    YES      0     110
3   300   288     NO      3     NaN
4   190   172    YES      2     185
5    70    64    YES      2     187
6   300   288     NO      3     NaN
7   190   172    YES      1     175
8    70    64    YES      4     188
虽然我遇到了以下错误-TypeError:CannotbeIndexbyLocationIndex带有一个非整数键,但我尝试创建列时使用了np.where方法

df['Dyn_Ave'] = np.where(df['C'] == 'YES', df['A'].iloc[df['D']:df.loc['C'][-1]].mean(), np.nan)
让我们试试:

s = df['A'].cumsum().shift(fill_value=0)

df['Dyn_Ave'] = np.where(df['C'] == 'YES', 
                         (s - s.reindex(df['D']).values) / (np.arange(len(df)) - df['D']),           
                         np.nan)
输出:

     A    B    C  D     Dyn_Ave
0  100   80   NO  0         NaN
1  120   50   NO  1         NaN
2   70   64  YES  0  110.000000
3  300  288   NO  3         NaN
4  190  172  YES  2  185.000000
5   70   64  YES  2  186.666667
6  300  288   NO  3         NaN
7  190  172  YES  1  175.000000
8   70   64  YES  4  187.500000

解释:首先让我们暂时忘记
C=='YES'
,注意动态平均值。从第
df['D']
行到第
j-1行的平均值可以看作

(cumsum[j-1] - cumsum[df['D']-1])/(j-df['D'])
或:

这就是为什么我们首先计算积和,然后移动它:

s = df['A'].cumsum().shift(fill_value=0)
为了在
df['D']
处获得总和,我们使用reindex并传递基础numpy数组进行减法:

(s - s.reindex(df['D']).values)
行数可以很容易地看出为:

(np.arange(len(df)) - df['D'])

最后一部分只是填写where
C==“YES”
,正如您试图完成的那样。

您可以使用
df.apply
,但它将比
np.where

df['Dyn_Ave']=df[df.C=='YES'].apply(lambda x:np.round(df.A.loc[x.D:x.name-1].mean()),轴=1)
df
输出:


您对每个组件的详细解释极大地帮助了我理解这些概念,并完美地解决了我的问题。谢谢你,谢谢你。然而,我正试图在我的项目中保持尽可能快的速度,这就是为什么
np。在
版本更适合的地方没有问题,@QuangHoang的不仅(可能)更快,而且对你问题的结构有着非常迷人的洞察力。
(np.arange(len(df)) - df['D'])
     A    B    C  D  Dyn_Ave
0  100   80   NO  0      NaN
1  120   50   NO  1      NaN
2   70   64  YES  0    110.0
3  300  288   NO  3      NaN
4  190  172  YES  2    185.0
5   70   64  YES  2    187.0
6  300  288   NO  3      NaN
7  190  172  YES  1    175.0
8   70   64  YES  4    188.0