Python 3.x 从表中创建时间序列数据

Python 3.x 从表中创建时间序列数据,python-3.x,pandas,numpy,time-series,Python 3.x,Pandas,Numpy,Time Series,我有一张像这样的桌子 import numpy as np import pandas as pd tmp=[["","5-9",""],["","",""],["17-","","4- -9 27-"],["-6","",""],["","","-15"]] dat=pd.DataFrame(tmp).rename(columns={0:"V0",1:"V1",2:"V2"}) dat["Month"]=np.arange(1,6) dat["Year"]=np.repeat(2015,5)

我有一张像这样的桌子

import numpy as np
import pandas as pd
tmp=[["","5-9",""],["","",""],["17-","","4- -9 27-"],["-6","",""],["","","-15"]]
dat=pd.DataFrame(tmp).rename(columns={0:"V0",1:"V1",2:"V2"})
dat["Month"]=np.arange(1,6)
dat["Year"]=np.repeat(2015,5)

    V0   V1         V2  Month  Year
0       5-9                 1  2015
1                           2  2015
2  17-       4- -9 27-      3  2015
3   -6                      4  2015
4                  -15      5  2015
...
表中的数字表示特定事件发生的天数(当月)。注意:月份可以有多个事件,事件可以跨越多个月

V1、V2和V3是三种不同的设备,每种设备都有自己的独立事件。我们有三个不同的时间序列

我想将此表转换为一个时间序列数据帧,即每天对每个设备进行细分。每行将是一个月(一年)的一天,每列现在只有0或1的值,如果当天没有发生事件,则为0,否则为1(虚拟变量)。结果将包含三个不同的时间序列,每个设备一个。我该怎么做

这就是输出的样子

    V0  V1  V2  Day  Month  Year
0    0   0   0    1      1  2015
1    0   0   0    2      1  2015
2    0   0   0    3      1  2015
3    0   0   0    4      1  2015
4    0   0   0    5      1  2015
5    0   1   0    6      1  2015
6    0   1   0    7      1  2015
7    0   1   0    8      1  2015
8    0   1   0    9      1  2015
9    0   1   0   10      1  2015
10   0   0   0   11      1  2015
11   0   0   0   12      1  2015
12   0   0   0   13      1  2015
...

您可以通过如下所示的一系列转换来实现这一点。不知道这是不是最有效的方法

import numpy as np
import pandas as pd
tmp=[["","5-9",""],["","",""],["17-","","4- -9 27-"],["-6","",""],["","","-15"]]
df=pd.DataFrame(tmp).rename(columns={0:"V0",1:"V1",2:"V2"})
df["Month"]=np.arange(1,6)
df["Year"]=np.repeat(2015,5)
print(df)
1。仅堆叠非空值

days = df.set_index(['Year', 'Month']).stack().replace('', np.nan).dropna()
print(days)
days_fr = days_ex.apply(lambda x: pd.Series(x, index=np.arange(1, 32)))
print(days_fr)
days_stacked = days_unstacked.unstack('Devices').fillna(0).reset_index()
print(days_stacked.head(10))
2。扩展日期范围

days = df.set_index(['Year', 'Month']).stack().replace('', np.nan).dropna()
print(days)
days_fr = days_ex.apply(lambda x: pd.Series(x, index=np.arange(1, 32)))
print(days_fr)
days_stacked = days_unstacked.unstack('Devices').fillna(0).reset_index()
print(days_stacked.head(10))
诸如
“5-9”
之类的字符串需要转换为长度为31的数组,索引5-9之间的值设置为1,其余值设置为0。同样,对于其他行。这是一个字符串解析问题,留作练习:-)。在下面的示例中,我将根据问题中的值对解决方案进行硬编码

def _fill(arr, start, stop):
  arr[np.arange(start-1, stop)] = 1
  return arr

def expand_days(df_in):
  df_out = df_in.copy()
  days_all = np.zeros(31)

  df_out.loc[2015, 1, 'V1'] = _fill(days_all.copy(), 5, 9)
  df_out.loc[2015, 3, 'V0'] = _fill(days_all.copy(), 17, 31)
  df_out.loc[2015, 3, 'V2'] = _fill(_fill(days_all.copy(), 4, 9), 27, 31)
  df_out.loc[2015, 4, 'V0'] = _fill(days_all.copy(), 1, 6)
  df_out.loc[2015, 5, 'V2'] = _fill(days_all.copy(), 1, 15)

  return df_out

days_ex = expand_days(days)
print(days_ex)
3。将数组转换为一系列列

days = df.set_index(['Year', 'Month']).stack().replace('', np.nan).dropna()
print(days)
days_fr = days_ex.apply(lambda x: pd.Series(x, index=np.arange(1, 32)))
print(days_fr)
days_stacked = days_unstacked.unstack('Devices').fillna(0).reset_index()
print(days_stacked.head(10))
4。设置正确的索引名和堆栈

days_unstacked = days_fr.stack()
days_unstacked.index.set_names(['Year', 'Month', 'Devices', 'Days'], inplace=True)
print(days_unstacked.head())
5。取消堆叠并用零填充NA

days = df.set_index(['Year', 'Month']).stack().replace('', np.nan).dropna()
print(days)
days_fr = days_ex.apply(lambda x: pd.Series(x, index=np.arange(1, 32)))
print(days_fr)
days_stacked = days_unstacked.unstack('Devices').fillna(0).reset_index()
print(days_stacked.head(10))

结果帧的索引名被设置为
Devices
,这是我们如何设置问题的工件。需要将其更改为其他内容。

W/V1、V1和V2三列之间的区别是什么?@Peter V1、V2和V3是三个不同的设备,每个设备都有自己的事件。因此,结果将是三个时间序列,每个V对应一个。双V1是一个输入错误。发布一个您希望输出的示例可能会有所帮助。