2

如何在 pandas 数据框中创建一个具有另一列梯度的列?

我希望梯度在滚动窗口上运行,因此一次只评估 4 个数据点。

我假设它是这样的: df['Gradient'] = np.gradient(df['Yvalues'].rolling(center=False,window=4))

但是,这会产生错误: raise ValueError('Length of values does not match length of ' 'index') ValueError: Length of values does not match length of index

有任何想法吗?

谢谢!!

4

2 回答 2

1

从给定的信息可以看出,您没有为滚动窗口提供聚合函数。

df['Gradient'] = np.gradient(df['Yvalues'].rolling(center=False,window=4).mean())

或者

df['Gradient'] = np.gradient(df['Yvalues'].rolling(center=False,window=4).sum())

您可以在此网站上阅读有关滚动功能的更多信息: https ://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.rolling.html

于 2018-01-04T07:20:38.660 回答
0

我想我找到了解决方案。虽然它可能不是最有效的..


class lines(object):
    def __init__(self):
        pass

    def date_index_to_integer_axis(self, dateindex):
        d = [d.date() for d in dateindex]
        days = [(d[x] - d[x-1]).days for x in range(0,len(d))]
        axis = np.cumsum(days)
        axis = [x - days[0] for x in axis]
        return axis

    def roll(self, Xvalues, Yvalues, w):  # Rollings Generator Function # https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python
        for i in range(len(Xvalues) + 1 - w):
            yield Xvalues[i:i + w], Yvalues[i:i + w]

    def gradient(self,Xvalues,Yvalues):
        #Uses least squares method.
        #Returns the gradient of two array vectors (https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.linalg.lstsq.html)
        A = np.vstack([Xvalues, np.ones(len(Xvalues))]).T
        m, c = np.linalg.lstsq(A, Yvalues)[0]
        return m,c

    def gradient_column(self, data, window):
        """ Takes in a single COLUMN EXTRACT from a DATAFRAME (with  associated "DATE" index) """
        vars = variables()

        #get "X" values
        Xvalues = self.date_index_to_integer_axis(data.index)
        Xvalues = np.asarray(Xvalues,dtype=np.float)
        #get "Y" values
        Yvalues = np.asarray([val for val in data],dtype=np.float)
        Yvalues = np.asarray(Yvalues,dtype=np.float)

        #calculate rolling window "Gradient" ("m" in Y = mx + c)
        Gradient_Col = [self.gradient(sx,sy)[0] for sx,sy in self.roll(Xvalues,Yvalues, int(window))]
        Gradient_Col = np.asarray(Gradient_Col,dtype=np.float)

        nan_array = np.empty([int(window)-1])
        nan_array[:] = np.nan
        #fill blanks at the start of the "Gradient_Col" so it is the same length as the original Dataframe (its shorter due to WINDOW)
        Gradient_Col = np.insert(Gradient_Col, 0, nan_array)

        return Gradient_Col



df['Gradient'] = lines.gradient_column(df['Operating Revenue'],window=4)


于 2018-01-05T01:42:38.663 回答