代码之家  ›  专栏  ›  技术社区  ›  normanius

建议使用什么方法计算pandas数据帧中选定列的加权和?

  •  3
  • normanius  · 技术社区  · 6 年前

    w .

    df = pd.DataFrame({'a': [1,2,3], 
                       'b': [10,20,30], 
                       'c': [100,200,300],
                       'd': [1000,2000,3000]})
    w = {'a': 1000., 'c': 10.}
    

    我自己想出了一些选择(见下文),但看起来都有点复杂。这个基本用例没有直接的pandas操作吗?有点像 df.wsum(w) ?


    我试过了 pd.DataFrame.dot ,但它会引发值错误:

    df.dot(pd.Series(w))
    # This raises an exception:
    # "ValueError: matrices are not aligned"
    

    通过为每列指定一个权重可以避免异常,但这是

    w = {'a': 1000., 'b': 0., 'c': 10., 'd': 0. }
    df.dot(pd.Series(w)) # This works
    

    如何计算列子集上的点积?或者,可以在应用点操作之前选择感兴趣的列,或者利用pandas/numpy忽略的事实 nan s计算(按行)和时(见下文)。

    w = {'a': 1000., 'c': 10.}
    
    # 1) Create a complete lookup W.
    W = { c: 0. for c in df.columns }
    W.update(w)
    ret = df.dot(pd.Series(W))
    
    # 2) Select columns of interest before applying the dot product.
    ret = df[list(w.keys())].dot(pd.Series(w))
    
    # 3) Exploit the handling of NaNs when computing the (row-wise) sum
    ret = (df * pd.Series(w)).sum(axis=1)
    # (df * pd.Series(w)) contains columns full of nans
    

    3 回复  |  直到 6 年前
        1
  •  3
  •   Dani Mesejo    6 年前

    您可以像在第一个示例中那样使用一个系列,然后使用reindex:

    import pandas as pd
    
    df = pd.DataFrame({'a': [1,2,3],
                       'b': [10,20,30],
                       'c': [100,200,300],
                       'd': [1000,2000,3000]})
    
    w = {'a': 1000., 'c': 10.}
    print(df.dot(pd.Series(w).reindex(df.columns, fill_value=0)))
    

    0    2000.0
    1    4000.0
    2    6000.0
    dtype: float64
    
        2
  •  2
  •   yatu Sayali Sonawane    6 年前

    这里有一个不必创建 pd.Series

    (df.loc[:,w.keys()] * list(w.values())).sum(axis=1)
    0    2000.0
    1    4000.0
    2    6000.0
    
        3
  •  1
  •   BENY    6 年前

    使用 numpy dot 有价值的

    df[list(w.keys())].values.dot(list(w.values()))
    array([2000., 4000., 6000.])
    

    df.mul( pd.Series(w),1).sum(axis=1)
    0    2000.0
    1    4000.0
    2    6000.0
    dtype: float64