Python 如何使不同长度的不同数据帧长度相等(下采样和上采样)
我有许多数据帧(时间序列),它们的长度在28到179之间。我要把它们做成104码长的。(对104以下的进行上采样,对104以上的进行下采样) 对于上采样,线性方法足以满足我的需要。对于下采样,值的平均值应良好 为了使所有文件都具有相同的长度,我认为需要使所有数据帧在相同的日期开始和结束 我能够使用以下代码行将所有样本缩减到最小数据帧(即28)的大小:Python 如何使不同长度的不同数据帧长度相等(下采样和上采样),python,pandas,time-series,interpolation,resampling,Python,Pandas,Time Series,Interpolation,Resampling,我有许多数据帧(时间序列),它们的长度在28到179之间。我要把它们做成104码长的。(对104以下的进行上采样,对104以上的进行下采样) 对于上采样,线性方法足以满足我的需要。对于下采样,值的平均值应良好 为了使所有文件都具有相同的长度,我认为需要使所有数据帧在相同的日期开始和结束 我能够使用以下代码行将所有样本缩减到最小数据帧(即28)的大小: df.set_index(pd.date_range(start='1/1/1991' ,periods=len(df), end='1/1/20
df.set_index(pd.date_range(start='1/1/1991' ,periods=len(df), end='1/1/2000'), inplace=True)
resampled=df.resample('120D').mean()
然而,当我将它们输入到我需要它们的模型中时,这不会给我带来好的结果,因为它会收缩较长的文件,从而扭曲数据
这就是我迄今为止所尝试的:
df.set_index(pd.date_range(start='1/1/1991' ,periods=len(df), end='1/1/2000'), inplace=True)
if df.shape[0]>100: resampled=df.resample('D').mean()
elif df.shape[0]<100: resampled=df.astype(float).resample('33D').interpolate(axis=0, method='linear')
else: break
假设平均长度为6,预期输出为:
使用插值将df1上采样到长度6,例如resamle(规则).interpolate()
使用重采样(规则).mean()
将df2下采样至长度6
更新:
如果我能将所有文件的采样值提升到179,那也没问题。我假设问题是,在提升采样的情况下,当您进行重采样时,其他值不会保留。对于示例df1,您可以通过在一列上使用
asfreq
来查看它:
print (df1.set_index(pd.date_range(start='1/1/1991' ,periods=len(df1), end='1/1/2000'))[1]
.resample('33D').asfreq().isna().sum(0))
#99 rows are nan on the 100 length resampled dataframe
因此,当您执行插值
而不是asfreq
时,它实际上只使用第一个值进行插值,这意味着第一个值在所有行上“重复”
要获得所需的结果,在插值之前,即使在上采样情况下也要使用mean
,例如:
print (df1.set_index(pd.date_range(start='1/1/1991' ,periods=len(df1), end='1/1/2000'))[1]
.resample('33D').mean().interpolate().head())
1991-01-01 3.000000
1991-02-03 3.060606
1991-03-08 3.121212
1991-04-10 3.181818
1991-05-13 3.242424
Freq: 33D, Name: 1, dtype: float64
你会得到你想要的值
总之,我认为在上采样和下采样情况下,可以使用相同的命令
resampled = (df.set_index(pd.date_range(start='1/1/1991' ,periods=len(df), end='1/1/2000'))
.resample('33D').mean().interpolate())
因为
插值
不会影响下采样情况下的结果。这是我使用skimage.transform.resize()函数的版本:
df1 = pd.DataFrame({
'a': [3,5,9,11],
'b': [-1,-3,-5,-7],
'c': [0,2,0,-2]
})
df1
a b c
0 3 -1 0
1 5 -3 2
2 9 -5 0
3 11 -7 -2
import pandas as pd
import numpy as np
from skimage.transform import resize
def df_resample(df1, num=1):
df2 = pd.DataFrame()
for key, value in df1.iteritems():
temp = value.to_numpy()/value.abs().max() # normalize
resampled = resize(temp, (num,1), mode='edge')*value.abs().max() # de-normalize
df2[key] = resampled.flatten().round(2)
return df2
df2 = df_resample(df1, 20) # resampling rate is 20
df2
a b c
0 3.0 -1.0 0.0
1 3.0 -1.0 0.0
2 3.0 -1.0 0.0
3 3.4 -1.4 0.4
4 3.8 -1.8 0.8
5 4.2 -2.2 1.2
6 4.6 -2.6 1.6
7 5.0 -3.0 2.0
8 5.8 -3.4 1.6
9 6.6 -3.8 1.2
10 7.4 -4.2 0.8
11 8.2 -4.6 0.4
12 9.0 -5.0 0.0
13 9.4 -5.4 -0.4
14 9.8 -5.8 -0.8
15 10.2 -6.2 -1.2
16 10.6 -6.6 -1.6
17 11.0 -7.0 -2.0
18 11.0 -7.0 -2.0
19 11.0 -7.0 -2.0
我认为pandas Groupby可能会在这方面有所帮助,但我对python不太熟悉,我不知道如何应用它来解决这个问题。最终我使用了:
resampled=(df.set_index(pd.date_range)(start='1/1/1991',periods=len(df),end='30/3/1991')。resample('20H')。mean().interpolate())
。产生的结果实际上是相同的(除了这些日期和规则产生的长度是106)。日期范围似乎更合理。@R.A抱歉,我没有遵循,结果与?我看到您更改了日期范围和重采样值,但您的意思是该方法不适用于这些设置?它给出了与中相同的结果,还执行了正确的上采样和下采样。这意味着开始和结束日期的更改实际上对最终结果影响不大。更改的日期更有意义,因为我的文件最长的长度是179。
df1 = pd.DataFrame({
'a': [3,5,9,11],
'b': [-1,-3,-5,-7],
'c': [0,2,0,-2]
})
df1
a b c
0 3 -1 0
1 5 -3 2
2 9 -5 0
3 11 -7 -2
import pandas as pd
import numpy as np
from skimage.transform import resize
def df_resample(df1, num=1):
df2 = pd.DataFrame()
for key, value in df1.iteritems():
temp = value.to_numpy()/value.abs().max() # normalize
resampled = resize(temp, (num,1), mode='edge')*value.abs().max() # de-normalize
df2[key] = resampled.flatten().round(2)
return df2
df2 = df_resample(df1, 20) # resampling rate is 20
df2
a b c
0 3.0 -1.0 0.0
1 3.0 -1.0 0.0
2 3.0 -1.0 0.0
3 3.4 -1.4 0.4
4 3.8 -1.8 0.8
5 4.2 -2.2 1.2
6 4.6 -2.6 1.6
7 5.0 -3.0 2.0
8 5.8 -3.4 1.6
9 6.6 -3.8 1.2
10 7.4 -4.2 0.8
11 8.2 -4.6 0.4
12 9.0 -5.0 0.0
13 9.4 -5.4 -0.4
14 9.8 -5.8 -0.8
15 10.2 -6.2 -1.2
16 10.6 -6.6 -1.6
17 11.0 -7.0 -2.0
18 11.0 -7.0 -2.0
19 11.0 -7.0 -2.0