【问题标题】:Broadcasting a list in Pandas在 Pandas 中广播列表
【发布时间】:2014-02-08 18:22:42
【问题描述】:

我有一个数据框 (a) ,我想从中减去一个列表 (b),按列:

import numpy as np
import pandas as pd

In:a=pd.DataFrame(np.arange(0,20).reshape(5,4))
   print(a)

Out:   0   1   2   3
   0   0   1   2   3
   1   4   5   6   7
   2   8   9  10  11
   3  12  13  14  15
   4  16  17  18  19

In: b=[1,2,3,4,5]

我希望这个操作可以工作:

c=a-b

但是我得到一个错误。

下面的操作做了我想要的,但它不优雅。这样做的正确方法是什么?

In: c=(a.T-b).T
    print(a)

Out:  0   1   2   3
  0  -1   0   1   2
  1   2   3   4   5
  2   5   6   7   8
  3   8   9  10  11
  4  11  12  13  14

【问题讨论】:

    标签: python numpy pandas broadcast


    【解决方案1】:

    我建议使用sub:

    >>> a = pd.DataFrame(np.arange(0,20).reshape(5,4))
    >>> b = [1,2,3,4,5]
    >>> a.sub(b, axis=0)
        0   1   2   3
    0  -1   0   1   2
    1   2   3   4   5
    2   5   6   7   8
    3   8   9  10  11
    4  11  12  13  14
    
    [5 rows x 4 columns]
    >>> np.allclose(a.sub(b,axis=0), (a.T-b).T)
    True
    

    【讨论】:

    • 我试图记住正确/更好的方法是什么,但不记得这个,所以我发布了apply 作为答案。
    • Ed,在这种情况下,'sub' 是我一直在寻找的东西,但我肯定会把 'apply lambda' 方法放在我的后兜里——队列中的下一个问题不是直接减法。谢谢!
    【解决方案2】:

    我认为这可能更容易阅读和理解:

    In [12]:
    
    import numpy as np
    a=pd.DataFrame(np.arange(0,20).reshape(5,4))
    b=[1,2,3,4,5]
    
    In [13]:
    
    print (a.T-array(b)).T
        0   1   2   3
    0  -1   0   1   2
    1   2   3   4   5
    2   5   6   7   8
    3   8   9  10  11
    4  11  12  13  14
    

    或者这样:

    a-(np.zeros(a.shape)+array(b)[...,np.newaxis])
    

    矩阵操作将是最慢的,内置.sub()@DSM 和数组广播方法将同样快:

    In [31]:                                  
    
    %timeit a.sub(b, axis=0)                  
    1000 loops, best of 3: 565 us per loop    
    In [32]:                                  
    
    %timeit a-(np.zeros(a.shape)+array(b)[...,np.newaxis])
    1000 loops, best of 3: 572 us per loop    
    In [33]:                                  
    
    %timeit (a.T-array(b)).T                
    1000 loops, best of 3: 896 us per loop
    

    如果您想知道,lambda 版本是最慢的,python 中经常出现这种情况:

    In [36]:
    
    %timeit a.apply(lambda x: x-b)
    100 loops, best of 3: 2.63 ms per loop
    

    【讨论】:

      【解决方案3】:

      您可以使用 apply 并使用 lambda 按列减去列表值:

      In [11]:
      
      import pandas as pd
      a=pd.DataFrame(np.arange(0,20).reshape(5,4))
      b=[1,2,3,4,5]
      
      a
      
      Out[11]:
      
          0   1   2   3
      0   0   1   2   3
      1   4   5   6   7
      2   8   9  10  11
      3  12  13  14  15
      4  16  17  18  19
      
      [5 rows x 4 columns]
      
      In [12]:
      
      c=a.apply(lambda x: x-b)
      c
      
      Out[12]:
      
          0   1   2   3
      0  -1   0   1   2
      1   2   3   4   5
      2   5   6   7   8
      3   8   9  10  11
      4  11  12  13  14
      
      [5 rows x 4 columns]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-01
        • 1970-01-01
        • 2020-06-09
        • 1970-01-01
        • 1970-01-01
        • 2012-10-21
        • 2021-09-08
        • 1970-01-01
        相关资源
        最近更新 更多