Python 熊猫的条件加权平均计算

Python 熊猫的条件加权平均计算,python,pandas,numpy,Python,Pandas,Numpy,我有2个数据帧,如下所示 Teacher\u Commission\u df如下 +---------+---------+----------+---------+ | Subject | Harare | Redcliff | Norton | +---------+---------+----------+---------+ | Science | 0.100 | 0.125 | 0.145 | +---------+---------+----------+-----

我有2个数据帧,如下所示

Teacher\u Commission\u df
如下

+---------+---------+----------+---------+
| Subject |  Harare | Redcliff |  Norton |
+---------+---------+----------+---------+
| Science |  0.100  |   0.125  |  0.145  |
+---------+---------+----------+---------+
| English |  0.125  |   0.150  |  0.170  |
+---------+---------+----------+---------+
|  Maths  |  0.090  |   0.115  |  0.135  |
+---------+---------+----------+---------+
|  Music  |  0.100  |   0.125  |  0.145  |
+---------+---------+----------+---------+
|  Total  |  0.415  |   0.515  |  0.595  |
+---------+---------+----------+---------+
Students\u df
如下所示。(请注意,哈拉雷和诺顿的
数学
学生不在

我需要计算每个城市的加权平均佣金,有一个条件

首先,我将给出所需的输出并解释方法

所需输出如下所示

+------------+--------+----------+--------+
| Total_Paid | Harare | Redcliff | Norton |
+------------+--------+----------+--------+
|   Science  |  4.62  |   4.37   |  6.30  |
+------------+--------+----------+--------+
|   English  |  13.46 |   9.61   |  11.46 |
+------------+--------+----------+--------+
|    Maths   |  0.00  |   5.58   |  0.00  |
+------------+--------+----------+--------+
|    Music   |  12.31 |   10.19  |  14.18 |
+------------+--------+----------+--------+
计算方法

如果在任何城市栏目中,
[Harare,Redcliff,Norton]
,如果任何学科的学生,
[Science,English,Mathematics,Music]
为零,则该学科的
教师委员会的
权重应删除

例如,在
Students\u df
中:选择城市
Harare
列的
Science
科目。由于
哈拉雷
中的
数学
,因此
教师佣金
的计算如下<代码>15*[0.10/(0.415-0.09)]=4.62
注意总分母中的
0.09
删除。其中,如
Radcliff
中所示,在不删除的情况下,其计算公式为
18*[0.125/0.515]=4.37

我希望我的解释清楚

这可以通过使用
IF
条件在
Microsoft Excel
中轻松完成。但是,我正在寻找一个可扩展的解决方案

我不知道如何开始计算过程。因此,请给我一个开始解决这个问题

-----------------------------------------------------------------------------------------
 UPDATE
  I've managed to solve this. Refer to my answer below and suggest for any improvements
------------------------------------------------------------------------------------------

那么,您需要的是dataframe中每个空null值的行/列索引

可以使用numpy.where()。根据空对象的数据类型,您可以

  • 将df加载为np数组
  • 一、 j=np.其中(“NaN”)
  • i和j现在是索引,如果大小相同,可以使用它们来消除权重,或者使用dataframe.index查找要删除的权重
  • 根据您的数据类型,将NaN替换为Null或“”

    这类似于使用IF在excel中执行的操作


    就我个人而言,我会制作一个复制的数据帧二进制文件,即在数据帧中有非空值的地方放一个1,在空位置放一个0,然后将两个向量混合。但是这可能是更多的处理开销

    所以,您需要的是数据帧中每个空空空值的行/列索引

    可以使用numpy.where()。根据空对象的数据类型,您可以

  • 将df加载为np数组
  • 一、 j=np.其中(“NaN”)
  • i和j现在是索引,如果大小相同,可以使用它们来消除权重,或者使用dataframe.index查找要删除的权重
  • 根据您的数据类型,将NaN替换为Null或“”

    这类似于使用IF在excel中执行的操作


    就我个人而言,我会制作一个复制的数据帧二进制文件,即在数据帧中有非空值的地方放一个1,在空位置放一个0,然后将两个向量混合。但是根据
    User:aak
    给出的建议,这可能需要更多的处理开销。我完全从
    numpy
    解决了这个问题

    # Load data and fill N/A values
    Teacher_Commission_df = pd.read_excel('data_Teacher.xlsx',index_col='Subject', skipfooter=1)
    Students_df = pd.read_excel('data_Studenst.xlsx',index_col='Subject')
    Students_df.fillna(value=0, inplace= True)
    
    
    # Convert Dataframes to Numpy Arrays
    T = Teacher_Commission_df.to_numpy(dtype='float')
    S = Students_df.to_numpy(dtype='float')
    
    # Filter index of ZERO values from Students Numpy Array and 
    # replace the correponding Values in teachers Numpy Array
    T[np.where(S == 0)] = 0
    
    # creat a temporary Sum numpy array for calculation
    Total_Teacher = T.sum(axis=0)
    
    #calculate incentives
    Calculations = T * (S/Total_Teacher)
    
    incentives = (pd.DataFrame(Calculations, columns=Students_df.columns, index=Students_df.index)
                      .round(decimals=2)
                      .reset_index())
    incentives
    

    根据
    用户给出的建议:aak
    。我完全从
    numpy
    解决了这个问题

    # Load data and fill N/A values
    Teacher_Commission_df = pd.read_excel('data_Teacher.xlsx',index_col='Subject', skipfooter=1)
    Students_df = pd.read_excel('data_Studenst.xlsx',index_col='Subject')
    Students_df.fillna(value=0, inplace= True)
    
    
    # Convert Dataframes to Numpy Arrays
    T = Teacher_Commission_df.to_numpy(dtype='float')
    S = Students_df.to_numpy(dtype='float')
    
    # Filter index of ZERO values from Students Numpy Array and 
    # replace the correponding Values in teachers Numpy Array
    T[np.where(S == 0)] = 0
    
    # creat a temporary Sum numpy array for calculation
    Total_Teacher = T.sum(axis=0)
    
    #calculate incentives
    Calculations = T * (S/Total_Teacher)
    
    incentives = (pd.DataFrame(Calculations, columns=Students_df.columns, index=Students_df.index)
                      .round(decimals=2)
                      .reset_index())
    incentives
    
    使用熊猫的解决方案 这实际上只是使用pandas的两行代码:

    将numpy导入为np
    df_tmp=teacher_commission_df[~students_df.isnull()]
    df=(df_tmp.div(df_tmp.apply(np.nansum,axis=0))*学生df.fillna(0)
    
    结果(使用新的3位精度数据)

    对上述代码的解释 注意:此解释使用原始问题中给出的2位精度数据

    • 首先,您可以通过使用
    [1]中的
    :students_df.isnull()
    出[1]:
    哈拉雷·雷德克里夫·诺顿
    主题
    科学谬误
    英语错
    数学真假真
    音乐假假假
    
    • 然后,您可以使用和not运算符(
      ~
      )从
      教师委员会
      中选择非空值
    [3]中的
    :教师委员会[u df[~students\u df.isnull()]
    出[3]:
    哈拉雷·雷德克里夫·诺顿
    主题
    科学0.10 0.13 0.15
    英语0.13 0.15 0.17
    数学NaN 0.12 NaN
    音乐0.10 0.13 0.15
    
    • 让我们将这个临时数据帧保存到新变量中,
      df\u tmp
    [12]中的
    df\u tmp=teacher\u commission\u df[~students\u df.isnull()]
    
    • 现在,我们要将每个单元格中的值除以列值之和。在和的帮助下,计算列值之和,忽略NaN:
    [14]中的
    :df_tmp.apply(np.nansum,axis=0)
    出[14]:
    哈拉雷0.33
    雷德克里夫0.53
    诺顿0.47
    数据类型:64
    
    • 然后,使用以下方法将求和与除法相结合:
    [15]中的
    df_tmp.div(df_tmp.apply(np.nansum,axis=0))
    出[15]:
    哈拉雷·雷德克里夫·诺顿
    主题
    科学0.303030 0.245283 0.319149
    英语0.393939 0.283019 0.361702
    数学NaN 0.226415 NaN
    音乐0.303030 0.245283 0.319149
    
    • 然后,将数据帧相乘(元素相乘):
    [16]中的
    df_tmp.div(df_tmp.apply(np.nansum,axis=0))*学生
    出[16]:
    哈拉雷·雷德克里夫·诺顿
    主题
    科学4.545455 4.415094 6.382979
    英语13.787879 9.339623 11.212766
    数学楠5.660377楠
    音乐12.121212 10.301887 14.361702
    
    • 最后,用零填充
      NaN
      值:
    [17]中的
    :(df_tmp.div(df_tmp.apply(np.nansum,axis=0))*学生df.fillna(0)
    出[17]:
    哈拉雷·雷德克里夫·诺顿
    主题
    科学4.545455 4.415094 6.382979
    英语13.787879 9.339623 11.212766
    数学0.0000005
    
    In [1]: df
    Out[1]:
                Harare   Redcliff     Norton
    Subject
    Science   4.615385   4.368932   6.304348
    English  13.461538   9.611650  11.456522
    Maths     0.000000   5.582524   0.000000
    Music    12.307692  10.194175  14.184783