如何将时间序列数据分割成3列3通道?
How to segment time series data into 3 column and 3 channels?
我有一个具有以下列名称的时间序列数据(1000 个数据点):
X、Y、Z、A、B。
我想生成 10 个段,每个段包含 3 个通道的 100 个数据点,其中第一个通道包含列 X,A,B,第二个通道 Y,A,B,第三个通道 Z,A,B ?
如何在 python 中完成此操作?
Numpy
要将时间序列重新排列为 10 个片段,只需使用 np.reshape
。
形状示例数据(XYZAB, timepoints)
:
a = np.random.randint(0,10,(5,1000))
print a.shape
>> (5L, 1000L)
重塑成十段,结果是(XYZAB, segments, timepoints)
:
b = np.reshape(a,(5,10,100))
print b.shape
>> (5L, 10L, 100L)
在这一点上,创建您所谓的 'channels' 可能并不理想,因为您会将数据的一部分(A 和 B)复制三份,而不会真正使访问该数据变得更容易。您可以访问例如XAB
就像这样:
xab = b[(0,3,4),:,:]
如果您绝对需要频道作为单独的副本,您可以像这样简单地获取它们:
c = np.array([b[(0,3,4),:,:],
b[(1,3,4),:,:],
b[(2,3,4),:,:]])
print c.shape
>> (3L, 3L, 10L, 100L)
这会生成一个形状为 (channel,column,segment,timepoints)
的数组,其中 column
指的是原始列名称(例如 (X,A,B)
表示通道 0
)。
Pandas
刚看到你问题上的 pandas
标签,所以...
df = pd.DataFrame(a.T, columns=list('XYZAB'))
分割成100个时间点的段作为dfs的列表:
segments = []
for group, segment in df.groupby(np.arange(len(df)) // 100):
segments.append(segment)
或者,更好的是,只需创建一个新列来指示每行属于哪个段:
df['segment'] = df.apply(lambda x : x.name // 100, axis=1)
在这一点上,最好不要将数据重复三次,而是按原样使用 df。您可以使用 df.groupby(['segment'])
轻松地按时间段应用操作,同时通过标准列选择来选择感兴趣的列,例如
df.groupby(['segment'])['X','A','B'].mean()
获取 X、A 和 B 列的每段平均值。
当然你可以创建例如'channels' 的列表或字典,如果你真的需要的话。
channels = {'XAB':df[['segment','X','A','B']],
'YAB':df[['segment','Y','A','B']],
'ZAB':df[['segment','Z','A','B']]}
你可以把它变成 pandas Panel
:
pnl = pd.Panel(channels)
要使用的最佳数据结构取决于您的特定用例,但通常我会避免使用面板并坚持使用 2D df
或 3D 数组(即 b
) .
我有一个具有以下列名称的时间序列数据(1000 个数据点):
X、Y、Z、A、B。
我想生成 10 个段,每个段包含 3 个通道的 100 个数据点,其中第一个通道包含列 X,A,B,第二个通道 Y,A,B,第三个通道 Z,A,B ?
如何在 python 中完成此操作?
Numpy
要将时间序列重新排列为 10 个片段,只需使用 np.reshape
。
形状示例数据(XYZAB, timepoints)
:
a = np.random.randint(0,10,(5,1000))
print a.shape
>> (5L, 1000L)
重塑成十段,结果是(XYZAB, segments, timepoints)
:
b = np.reshape(a,(5,10,100))
print b.shape
>> (5L, 10L, 100L)
在这一点上,创建您所谓的 'channels' 可能并不理想,因为您会将数据的一部分(A 和 B)复制三份,而不会真正使访问该数据变得更容易。您可以访问例如XAB
就像这样:
xab = b[(0,3,4),:,:]
如果您绝对需要频道作为单独的副本,您可以像这样简单地获取它们:
c = np.array([b[(0,3,4),:,:],
b[(1,3,4),:,:],
b[(2,3,4),:,:]])
print c.shape
>> (3L, 3L, 10L, 100L)
这会生成一个形状为 (channel,column,segment,timepoints)
的数组,其中 column
指的是原始列名称(例如 (X,A,B)
表示通道 0
)。
Pandas
刚看到你问题上的 pandas
标签,所以...
df = pd.DataFrame(a.T, columns=list('XYZAB'))
分割成100个时间点的段作为dfs的列表:
segments = []
for group, segment in df.groupby(np.arange(len(df)) // 100):
segments.append(segment)
或者,更好的是,只需创建一个新列来指示每行属于哪个段:
df['segment'] = df.apply(lambda x : x.name // 100, axis=1)
在这一点上,最好不要将数据重复三次,而是按原样使用 df。您可以使用 df.groupby(['segment'])
轻松地按时间段应用操作,同时通过标准列选择来选择感兴趣的列,例如
df.groupby(['segment'])['X','A','B'].mean()
获取 X、A 和 B 列的每段平均值。
当然你可以创建例如'channels' 的列表或字典,如果你真的需要的话。
channels = {'XAB':df[['segment','X','A','B']],
'YAB':df[['segment','Y','A','B']],
'ZAB':df[['segment','Z','A','B']]}
你可以把它变成 pandas Panel
:
pnl = pd.Panel(channels)
要使用的最佳数据结构取决于您的特定用例,但通常我会避免使用面板并坚持使用 2D df
或 3D 数组(即 b
) .