【问题标题】:Using pandas and scipy regression line slope to identify growth使用 pandas 和 scipy 回归线斜率来识别增长
【发布时间】:2018-05-18 20:36:32
【问题描述】:

我的目标是能够在记录表中识别价格增长。

我知道这可能与使用数据工具实现的功能相去甚远,因此我感谢任何帮助或改进建议。

我遇到的直接问题是,如果 pandas 行中的某些数据不存在,scipy.stats.linregress 不会返回。我认为需要某种掩蔽或填充来返回存在空值的行的斜率测量。抛出异常,但它仍然有效。

另外,我是否使用最佳解决方案来找到增长? 我观察到,如果我过滤具有正斜率、较高右值(相关性)和较低标准错误(标准错误)的记录,这些行的趋势线是向上且一致的。

我尝试使用斜率和其他数值来量化价格增长的原因是,如果我在 Excel 图表中绘制所有数据中的线条,那么选择显示一致向上移动的线条是压倒性的,因为有太多噪音。能不能做得更好?

这是工作示例:

# credit  jezrael

import pandas as pd
import numpy as np
import scipy
from scipy import stats

def calc_slope(row):
    a = scipy.stats.linregress(row, y=axisvalues)
    return pd.Series(a._asdict())

table=pd.DataFrame({'Category':['A','A','A','B','C','C','C','B','B','A','A','A','B','B','D','A','B','B'],
           'Quarter':['2016-Q1','2017-Q2','2017-Q3','2017-Q4','2017-Q2','2016-Q2','2017-Q2','2016-Q3','2016-Q4','2016-Q2','2016-Q3','2017-Q4','2016-Q1','2016-Q2','2016-Q4','2016-Q4','2017-Q2','2017-Q3'],
            'Value':[100,200,500,800,700,900,300,400,600,200,300,400,200,300,100,300,500,600]})

db=(table.groupby(['Category','Quarter']).filter(lambda group: len(group) >= 1)).groupby(['Category','Quarter'])["Value"].mean()

db=db.unstack()

axisvalues=list(range(1,len(db.columns)+1)) #used in calc_slope function

db = db.join(db.apply(calc_slope,axis=1))

【问题讨论】:

    标签: pandas scipy


    【解决方案1】:

    你可以使用:

    #np.arange instead range
    axisvalues= np.arange(1,len(db.columns)+1)
    
    def calc_slope(row):
        #mask NaNs out
        mask = row.notnull()
        a = scipy.stats.linregress(row[mask.values], y=axisvalues[mask])
        return pd.Series(a._asdict())
    
    
    db = db.join(db.apply(calc_slope,axis=1))
    print (db)
    
    print (db)
              2016-Q1  2016-Q2  2016-Q3  2016-Q4  2017-Q2  2017-Q3  2017-Q4  \
    Category                                                                  
    A           100.0    200.0    300.0    300.0    200.0    500.0    400.0   
    B           200.0    300.0    400.0    600.0    500.0    600.0    800.0   
    C             NaN    900.0      NaN      NaN    500.0      NaN      NaN   
    D             NaN      NaN      NaN    100.0      NaN      NaN      NaN   
    
                 slope  intercept    rvalue    pvalue    stderr  
    Category                                                     
    A         0.012895   0.315789  0.802955  0.029677  0.004281  
    B         0.010057  -0.885057  0.947623  0.001172  0.001516  
    C        -0.007500   8.750000 -1.000000  0.000000  0.000000  
    D              NaN        NaN  0.000000       NaN       NaN  
    

    但是对于最后一行获取RuntimeWarnings,因为2016-Q4 中只有一个值。

    对于删除警告,可以使用filterwarnings,谢谢Kdog

    import warnings 
    warnings.filterwarnings("ignore") 
    

    【讨论】:

    • 这样做了:导入警告;警告.filterwarnings(“忽略”)。在您看来,我是否应该寻找更好的方法来做到这一点?或者这是否与我将要确定的持续增长一样接近?
    • 是的,完全正确。谢谢你。我添加它来回答。
    猜你喜欢
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2013-09-27
    • 2021-02-25
    • 2015-09-09
    相关资源
    最近更新 更多