【问题标题】:Calculating formula based on multiple columns in Pandas Dataframe - but without creating many intermediate columns基于 Pandas Dataframe 中的多列计算公式 - 但不创建许多中间列
【发布时间】:2018-05-29 18:24:00
【问题描述】:

我一直在尝试根据包含股票代码价格历史的 Pandas 数据框计算“真实范围”公式。

这是公式:

TR = max [(high - low ), abs(high − close prev), abs ⁡(low − close prev)] 

我在数据框中有高、低和接近的列。

当我尝试这样操作时,我得到了无效的字符标识符错误,这不是很有帮助。我在下面的表达式中尝试了很多变化和组合,但没有成功。

df['TR']=((df['high']-df['low']), (df['high'] - df['adjclose'].shift(1)).abs(),(df['low'] - df['adjclose'].shift(1))).max(axis=1)

我知道这可以通过三个独立的中间列并取其中的最大值来实现。但是,我想避免同样的事情,直接去做。

有出路吗?

【问题讨论】:

    标签: python pandas numpy


    【解决方案1】:

    concatmax 一起使用:

    df['TR'] = pd.concat([(df['high'] - df['low']), 
                          (df['high'] - df['adjclose'].shift(1)).abs(),
                          (df['low']  - df['adjclose'].shift(1))], axis=1).max(axis=1)
    

    示例

    df = pd.DataFrame({'high':[4,5,4,5,5,4],
                       'low':[7,8,9,4,2,3],
                       'adjclose':[1,3,5,7,1,0]})
    
    print (df)
       adjclose  high  low
    0         1     4    7
    1         3     5    8
    2         5     4    9
    3         7     5    4
    4         1     5    2
    5         0     4    3
    
    df['TR'] = pd.concat([(df['high']-df['low']), 
                          (df['high'] - df['adjclose'].shift(1)).abs(),
                          (df['low'] - df['adjclose'].shift(1))], axis=1).max(axis=1)
    
    print (df)
      adjclose  high  low   TR
    0         1     4    7 -3.0
    1         3     5    8  7.0
    2         5     4    9  6.0
    3         7     5    4  1.0
    4         1     5    2  3.0
    5         0     4    3  3.0
    

    详情

    print (pd.concat([(df['high']-df['low']), 
                          (df['high'] - df['adjclose'].shift(1)).abs(),
                          (df['low'] - df['adjclose'].shift(1))], axis=1))
       0    1    2
    0 -3  NaN  NaN
    1 -3  4.0  7.0
    2 -5  1.0  6.0
    3  1  0.0 -1.0
    4  3  2.0 -5.0
    5  1  3.0  2.0
    

    Numpy 解决方案不同,因为行中 NaN 的最大值又是 NaN

    df['TR1'] = np.max(np.c_[(df['high']-df['low']), 
                            (df['high'] - df['adjclose'].shift(1)).abs(),
                            (df['low'] - df['adjclose'].shift(1))], axis=1)
    
    print (df)
       adjclose  high  low  TR1
    0         1     4    7  NaN
    1         3     5    8  7.0
    2         5     4    9  6.0
    3         7     5    4  1.0
    4         1     5    2  3.0
    5         0     4    3  3.0
    
    print (np.c_[(df['high']-df['low']), 
                            (df['high'] - df['adjclose'].shift(1)).abs(),
                            (df['low'] - df['adjclose'].shift(1))])
    
    [[-3. nan nan]
     [-3.  4.  7.]
     [-5.  1.  6.]
     [ 1.  0. -1.]
     [ 3.  2. -5.]
     [ 1.  3.  2.]] 
    

    【讨论】:

    • 有道理:)!
    • @RafaelC - 我添加了 numpy 解决方案,得到NaN
    • 谢谢。只是为了完整起见,错过了公式中的第二个 abs() - 这是我的错误(与问题的技术部分和出色的技术答案无关),但为了记录起见,为阅读 True range 公式的人进行纠正(从财务角度来看:正确的公式缺少一个 abs()。添加回来。df['TR'] = pd.concat([(df['high']-df['low']),(df ['high'] - df['adjclose'].shift(1)).abs(),(df['low'] - df['adjclose'].shift(1)).abs()], 轴=1).max(axis=1)
    【解决方案2】:

    可以通过以下方式完成:

    df['TR']=list(map(max,zip((df['high']-df['low']), (df['high'] - df['adjclose'].shift(1)).abs(),(df['low'] - df['adjclose'].shift(1)))))
    

    【讨论】:

      猜你喜欢
      • 2019-09-07
      • 1970-01-01
      • 2013-01-15
      • 2016-02-10
      • 2016-06-19
      • 1970-01-01
      • 2021-12-30
      • 2011-02-15
      • 1970-01-01
      相关资源
      最近更新 更多