【问题标题】:Pandas reverse of diff()diff()的熊猫反转
【发布时间】:2018-09-28 21:24:57
【问题描述】:

我已经计算了一个系列中连续值之间的差异,但我无法使用diffinv() 反转/取消差异:

ds_sqrt = np.sqrt(ds)
ds_sqrt = pd.DataFrame(ds_sqrt)
ds_diff = ds_sqrt.diff().values

我怎样才能消除这种差异?

【问题讨论】:

标签: python arrays python-3.x pandas numpy


【解决方案1】:

您可以通过numpy 执行此操作。算法courtesy of @Divakar.

当然,你需要知道你的系列中的第一个项目才能工作。

df = pd.DataFrame({'A': np.random.randint(0, 10, 10)})
df['B'] = df['A'].diff()

x, x_diff = df['A'].iloc[0], df['B'].iloc[1:]
df['C'] = np.r_[x, x_diff].cumsum().astype(int)

#    A    B  C
# 0  8  NaN  8
# 1  5 -3.0  5
# 2  4 -1.0  4
# 3  3 -1.0  3
# 4  9  6.0  9
# 5  7 -2.0  7
# 6  4 -3.0  4
# 7  0 -4.0  0
# 8  8  8.0  8
# 9  1 -7.0  1

【讨论】:

    【解决方案2】:

    您可以使用 pmdarima.Docs link 中的 diff_inv

    # genarating random table
      np.random.seed(10)
      vals = np.random.randint(1, 10, 6)
      df_t = pd.DataFrame({"a":vals})
    
      #creating two columns with diff 1 and diff 2
      df_t['dif_1'] = df_t.a.diff(1)
      df_t['dif_2'] = df_t.a.diff(2)
    
      df_t
    
        a   dif_1   dif_2
      0 5   NaN     NaN
      1 1   -4.0    NaN
      2 2   1.0    -3.0
      3 1   -1.0    0.0
      4 2   1.0     0.0
      5 9   7.0     8.0
    

    然后创建一个函数,该函数将返回一个具有反向 diff 值的数组。

    from pmdarima.utils import diff_inv
    
    def inv_diff (df_orig_column,df_diff_column, periods):
        # Generate np.array for the diff_inv function - it includes first n values(n = 
        # periods) of original data & further diff values of given periods
        value = np.array(df_orig_column[:periods].tolist()+df_diff_column[periods:].tolist())
    
        # Generate np.array with inverse diff
        inv_diff_vals = diff_inv(value, periods,1 )[periods:]
        return inv_diff_vals
    

    使用示例:

    # df_orig_column - column with original values
    # df_diff_column - column with differentiated values
    # periods - preiods for pd.diff()
    inv_diff(df_t.a, df_t.dif_2, 2) 
    

    输出:

    array([5., 1., 2., 1., 2., 9.])
    

    【讨论】:

      【解决方案3】:

      这是一个工作示例。

      首先,让我们导入需要的包

      import numpy as np
      import pandas as pd
      
      import pmdarima as pm
      
      import matplotlib.pyplot as plt
      import seaborn as sns
      sns.set()
      

      然后,让我们创建一个简单的离散余弦波

      period = 5
      cycles = 7
      x = np.cos(np.linspace(0, 2*np.pi*cycles, periods*cycles+1))
      X = pd.DataFrame(x)
      

      和情节

      fig, ax = plt.subplots(figsize=(12, 5))
      ax.plot(X, marker='.')
      ax.set(
          xticks=X.index
      )
      ax.axvline(0, color='r', ls='--')
      ax.axvline(period, color='r', ls='--')
      ax.set(
          title='Original data'
      )
      plt.show()
      

      注意句号是5。现在让我们通过区分第 5 期来消除这种“季节性”

      X_diff = X.diff(periods=period)
      # NOTE: the first `period` observations
      #       are needed for back transformation
      X_diff.iloc[:period] = X[:period]
      

      请注意,我们必须保留第一个 period 观察结果以允许反向转换。如果您不需要它们,则必须将它们保留在其他地方,然后在您想要反向转换时连接起来。

      fig, ax = plt.subplots(figsize=(12, 5))
      ax.axvline(0, color='r', ls='--')
      ax.axvline(period-1, color='r', ls='--')
      ax.plot(X_diff, marker='.')
      ax.annotate(
          'Keep these original data\nto allow back transformation',
          xy=(period-1, .5), xytext=(10, .5),
          arrowprops=dict(color='k')
      )
      ax.set(
          title='Transformed data'
      )
      plt.show()
      

      现在让我们使用pmdarima.utils.diff_inv 来转换数据

      X_diff_inv = pm.utils.diff_inv(X_diff, lag=period)[period:]
      

      请注意,我们会丢弃第一个 period 结果,这将是 0 并且不需要。

      fig, ax = plt.subplots(figsize=(12, 5))
      ax.axvline(0, color='r', ls='--')
      ax.axvline(period-1, color='r', ls='--')
      ax.plot(X_diff_inv, marker='.')
      ax.set(
          title='Back transformed data'
      )
      plt.show()
      

      【讨论】:

      • 我用你的代码得到了不同的情节
      【解决方案4】:

      用 pandas 在一行中反转 diff

      import pandas as pd
      
      df = pd.DataFrame([10, 15, 14, 18], columns = ['Age'])
      df['Age_diff'] = df.Age.diff()
      
      df['reverse_diff'] = df['Age'].shift(1) + df['Age_diff']
      
      print(df)
      
          Age  Age_diff  reverse_diff
      0   10       NaN           NaN
      1   15       5.0          15.0
      2   14      -1.0          14.0
      3   18       4.0          18.0  
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-21
        • 1970-01-01
        • 2018-11-09
        • 2017-12-19
        • 2021-02-02
        • 2016-05-24
        相关资源
        最近更新 更多