如何处理大熊猫不同长度的时间序列?

时间:2020-05-15 18:38:37

标签: python pandas dataframe time-series data-science

我有一个数据矩阵,其中每一行都被视为时间序列,但长度不同。看起来是这样的:

This is how it looks like

在文本中:

0 1 2 3 4 5 6 7 8 9

0 12 32 45 67 89 54 23.0 56.0 78.0 98.0

1 34 76 34 89 34 3 NaN NaN NaN NaN

2 76 34 54 12 43 78 56.0 NaN NaN NaN

3 76 56 45 23 43 45 67.0 76.0 67.0 8.0

4 87 9 9 0 89 90 6.0 89.0 NaN NaN

5 23 90 90 32 23 34 56.0 9.0 56.0 87.0

6 23 56 34 3 5 8 7.0 6.0 98.0 NaN

7 32 23 34 6 65 78 67.0 87.0 89.0 87.0

8 12 23 34 32 43 67 45.0 NaN NaN NaN

9 343 76 56 7 8 9 4.0 5.0 8.0 68.0

我曾尝试使用熊猫代码读取数据:

timeseries=pd.read_excel('timeseries.xlsx',header=None)
######   timeseries   ##############
print(timeseries)

然后我想将数据矩阵的每一行传递给时间序列分析模型,该模型将为每个时间序列生成一个值,并且在传递所有时间序列后,我将获得一个特征向量。

我曾尝试使用以下代码实现:

features=[]
for i,j in timeseries.iterrows():
    row=timeseries.iloc[i]
    model=AR(row.values)
    model_fit=model.fit()
    yhat=model_fit.predict(len(row),len(row))
    features.append(yhat)
fvector=pd.DataFrame(features)
print(fvector)

但是我认为这是错误的

MissingDataError:exog包含inf或nans

据我所知,它是由于分析方法限制了NaN值并引发此错误而发生的,但根据我的情况,每个时间序列都应被视为分析方法的独立输入,并且应读取到最后一个实数每行。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

您需要删除NaN并将其替换为0或其他值:

timeseries.fillna(0, inplace=True)
print(timeseries)
features=[]
for i,j in timeseries.iterrows():
    row=timeseries.iloc[i]
    model=AR(row.values)
    model_fit=model.fit()
    yhat=model_fit.predict(len(row),len(row))
    features.append(yhat)
fvector=pd.DataFrame(features)
print(fvector)

            0
0  100.704274
1    0.000000
2    0.000000
3  -23.468840
4   19.943124
5   37.442981
6    5.771667
7  105.138431
8    0.000000
9  237.903666

答案 1 :(得分:0)

您的示例未显示所有所需的详细信息,例如你写了 关于 AR 的一切。

据我了解,您的软件抱怨某些行中的 NaN 值, 所以你应该:

  • 从每一行中消除 NaN 值,
  • 仅在之后对其进行处理。

这一次与执行速度有关的另一个细节是,如果您遍历行,则:

  • 循环的第二个控制值已经包含当前行,
  • 因此按索引重新读取是没有意义的。

因此,更改代码,如下所示:

for i, row in timeseries.iterrows():
    row = row.dropna()
    print(f'{i}: {row.size:2}  {row.values}')
    # Any further processing of "row"

当然, print 仅用于演示目的。 将其放入代码的目标版本中。

我怀疑是否用零代替 NaN 值(建议 在另一个答案中)是正确的方法,因为它可能会“破坏” 您模型中的某些东西。

编辑

如果您只想处理当前行的“初始”部分,即 根据您在评论中的要求,直到第一个 Nan (不包括), 将对 dropna()的调用替换为:

row = row[row.isna().cumsum() == 0]

要检查其工作原理,请替换例如索引行中最后一个 NaN 1 具有一些有限值,并观察该行的结果。

答案 2 :(得分:0)

您可以使用NumPy并将缺少的值输入为np.NaN。 然后,您可以将数据读取为NumPy数组,进行转置(因为在熊猫中,时间序列应该是列而不是行),将其转换为DataFrame,设置DatetimeIndex并从那里获取。

例如:

import numpy as np
import pandas as pd

data = np.asarray([[12, 32, 45, 67, 89, 54, 23.0, 56.0, 78.0, 98.0],
                   [34, 76, 34, 89, 34, 3, np.NaN, np.NaN, np.NaN, np.NaN],
                   [76, 34, 54, 12, 43, 78, 56.0, np.NaN, np.NaN, np.NaN],
                   [76, 56, 45, 23, 43, 45, 67.0, 76.0, 67.0, 8.0],
                   [87, 9, 9, 0, 89, 90, 6.0, 89.0, np.NaN, np.NaN],
                   [23, 90, 90, 32, 23, 34, 56.0, 9.0, 56.0, 87.0],
                   [23, 56, 34, 3, 5, 8, 7.0, 6.0, 98.0, np.NaN],
                   [32, 23, 34, 6, 65, 78, 67.0, 87.0, 89.0, 87.0],
                   [12, 23, 34, 32, 43, 67, 45.0, np.NaN, np.NaN, np.NaN],
                   [343, 76, 56, 7, 8, 9, 4.0, 5.0, 8.0, 68.0]])

df = pd.DataFrame(data.T)
df.index = pd.DatetimeIndex(pd.date_range('2020-05-15', periods=10, freq='d'))

df
               0       1       2       3       4       5       6       7       8        9
2020-05-15  12.0    34.0    76.0    76.0    87.0    23.0    23.0    32.0    12.0    343.0
2020-05-16  32.0    76.0    34.0    56.0    9.0     90.0    56.0    23.0    23.0    76.0
2020-05-17  45.0    34.0    54.0    45.0    9.0     90.0    34.0    34.0    34.0    56.0
2020-05-18  67.0    89.0    12.0    23.0    0.0     32.0    3.0     6.0     32.0    7.0
2020-05-19  89.0    34.0    43.0    43.0    89.0    23.0    5.0     65.0    43.0    8.0
2020-05-20  54.0    3.0     78.0    45.0    90.0    34.0    8.0     78.0    67.0    9.0
2020-05-21  23.0    NaN     56.0    67.0    6.0     56.0    7.0     67.0    45.0    4.0
2020-05-22  56.0    NaN     NaN     76.0    89.0    9.0     6.0     87.0    NaN     5.0
2020-05-23  78.0    NaN     NaN     67.0    NaN     56.0    98.0    89.0    NaN     8.0
2020-05-24  98.0    NaN     NaN     8.0     NaN     87.0    NaN     87.0    NaN     68.0

有关详细信息,请参见pandas Time Series documentation.

如果模型函数确实不接受任何缺失值,则可能必须以某种方式猜测它们。这当然会影响模型的可靠性。请参见pandas documentation,尤其是df.fillna(),以及Wikipedia article on Imputation

如果适合您的模型,您还可以从上述数据框中提取单个时间序列,而不会缺少任何值。例如。第二列:

df[1].dropna()
2020-05-15    34.0
2020-05-16    76.0
2020-05-17    34.0
2020-05-18    89.0
2020-05-19    34.0
2020-05-20     3.0
Freq: D, Name: 1, dtype: float64
相关问题