numpy 如何在python中正确复制excel summproduct函数?

pkln4tw6  于 2023-01-09  发布在  Python
关注(0)|答案(2)|浏览(142)

我有一个类似下面的数据框,我需要计算加权平均值。在excel中,如果我使用sumproduct函数,我会得到15.25的结果。但是,当我使用下面的代码时,它给我0。如何在代码中更正这个问题?

import pandas as pd
df1 = { 'product1':['N/A'],
  'product2':[15.25],
  'p1 weight':[0],
  'p2 weight':[4]}

df1=pd.DataFrame(df1)
df1.fillna(0,inplace=True)

cols_left = [c for c in df1.columns if 'product' in c]
cols_right = [c for c in df1.columns if 'weight' in c]

result = (df1[cols_left] * df1[cols_right]).sum(axis=1) / df1[cols_right].sum(axis=1)
df1['result'] = result

结果如下

注意,我必须使用cols_left和cols_right方法,因为在我的真实的工作情况中,我有+100列需要基于相应列执行加权平均计算。
我没有像df1['result1'] = (df1['product1'] * df1['p1 weight'] + df1['product2'] * df1['p2 weight'] )/ df1['p1 weight'] + df1['p2 weight']等那样进行硬编码,而是在计算和积之前将所有对应的列分别分组到cols_left和cols_right中。
如有任何建议,我们将不胜感激。

3yhwsihp

3yhwsihp1#

纽比方法:

下面例子中的df1在我回答的最后一节中定义
解决这个问题的最简单的方法是取一个np.nanprod,然后再取一个.sum(),这个答案的灵感来自this StackOverflow solution

A = df1.iloc[:,:2].values
B = df1.iloc[:,2:].values

num = np.nanprod(np.dstack((A,B)),2).sum(1)
den = df1.iloc[:,2:].sum(1)

df1['sumproduct'] = num/den
print(df1)
product1  product2  p1 weight  p2 weight  sumproduct
0       NaN     15.25          0          4       15.25
1      10.0     10.00          2          3       10.00
2       8.0      2.00          5          1        7.00

Pandas方法:

Pandas的方法可能有点复杂,因为pandas.DataFrame.dot(基本上就是你想要的和积)在处理不同列名的 Dataframe 时没有给你很大的灵活性,但是,你可以使用pandas.groupby和一个自定义的grouper来轻松地做乘积。
尝试这种受this StackOverflow answer启发的方法-
一个二个一个一个

    • PS**-我使用这个 Dataframe 和一些附加行来演示上述解决方案。同时,我使用正确的np.nan代替NAN字符串来实现虚拟输入。
import pandas as pd
import numpy as np   #for adding proper Nans instead of strings

## added a few more rows for testing ##
#######################################
df1 = { 'product1':[np.nan,10,8],
        'product2':[15.25,10,2],
        'p1 weight':[0,2,5],
        'p2 weight':[4,3,1]}

df1=pd.DataFrame(df1)
#######################################
wixjitnu

wixjitnu2#

Pandas支持(并强制)数据对齐。当您对两个数据框应用操作时,该操作将应用于具有相同索引(名称)的行和列,而不是在相同位置。要对具有不同名称的一对列应用操作,您应该从中提取底层numpy数组:

# Clean the NAs
import numpy as np
df1.replace("N/A", np.nan, inplace=True)

(df1[cols_left].fillna(0).values * df1[cols_right].values).sum() / df1[cols_right].sum(1)
#0    15.25

注意,nan * 0仍然是nan,必须将nan s转换为有限数(例如,转换为0)才能获得数值结果。

相关问题