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