合并两个Pandas数据帧,在一个时间列上重新采样,进行插值

时间:2014-10-22 21:06:41

标签: python pandas

这是我关于stackoverflow的第一个问题。放轻松我!

我有两个不同采集系统同时采集的数据集,采样率不同。一个是非常规则的,另一个则不是。我想创建一个包含两个数据集的数据帧,使用规则间隔的时间戳(以秒为单位)作为两者的参考。不规则采样的数据应在规则间隔的时间戳上进行插值。

这里有一些玩具数据证明了我正在做的事情:

import pandas as pd
import numpy as np

# evenly spaced times
t1 = np.array([0,0.5,1.0,1.5,2.0])
y1 = t1

# unevenly spaced times
t2 = np.array([0,0.34,1.01,1.4,1.6,1.7,2.01])
y2 = 3*t2

df1 = pd.DataFrame(data={'y1':y1,'t':t1})
df2 = pd.DataFrame(data={'y2':y2,'t':t2})

df1和df2看起来像这样:

df1:
    t   y1
0  0.0  0.0
1  0.5  0.5
2  1.0  1.0
3  1.5  1.5
4  2.0  2.0

df2:
    t    y2
0  0.00  0.00
1  0.34  1.02
2  1.01  3.03
3  1.40  4.20
4  1.60  4.80
5  1.70  5.10
6  2.01  6.03

我尝试合并df1和df2,在df1.t上插入y2。期望的结果是:

df_combined:
     t   y1   y2
0  0.0  0.0  0.0
1  0.5  0.5  1.5
2  1.0  1.0  3.0
3  1.5  1.5  4.5
4  2.0  2.0  6.0

我一直在阅读pandas.resample的文档,以及搜索以前的stackoverflow问题,但是我们还没有找到解决我的特定问题的方法。有任何想法吗?看起来应该很容易。

更新: 我想出了一个可能的解决方案:首先插入第二个系列,然后附加到第一个数据框:

from scipy.interpolate import interp1d
f2 = interp1d(t2,y2,bounds_error=False)
df1['y2'] = f2(df1.t)

给出:

df1:
    t   y1   y2
0  0.0  0.0  0.0
1  0.5  0.5  1.5
2  1.0  1.0  3.0
3  1.5  1.5  4.5
4  2.0  2.0  6.0

这有效,但如果有更好的方法,我仍然可以接受其他解决方案。

2 个答案:

答案 0 :(得分:4)

如果从Series中构造单个DataFrame,则使用时间值作为索引,如下所示:

>>> t1 = np.array([0, 0.5, 1.0, 1.5, 2.0])
>>> y1 = pd.Series(t1, index=t1)

>>> t2 = np.array([0, 0.34, 1.01, 1.4, 1.6, 1.7, 2.01])
>>> y2 = pd.Series(3*t2, index=t2)

>>> df = pd.DataFrame({'y1': y1, 'y2': y2})
>>> df
       y1    y2
0.00  0.0  0.00
0.34  NaN  1.02
0.50  0.5   NaN
1.00  1.0   NaN
1.01  NaN  3.03
1.40  NaN  4.20
1.50  1.5   NaN
1.60  NaN  4.80
1.70  NaN  5.10
2.00  2.0   NaN
2.01  NaN  6.03

您只需interpolate,然后只选择定义y1的部分:

>>> df.interpolate('index').reindex(y1)
      y1   y2
0.0  0.0  0.0
0.5  0.5  1.5
1.0  1.0  3.0
1.5  1.5  4.5
2.0  2.0  6.0

答案 1 :(得分:0)

我不清楚你是如何摆脱y2中的某些值的,但似乎如果给定时间点有多个值,你只需要第一个。此外,您的时间值似乎应该在索引中。我还添加了列标签。它看起来像这样:

import pandas as pd

# evenly spaced times
t1 = [0,0.5,1.0,1.5,2.0]
y1 = t1

# unevenly spaced times
t2 = [0,0.34,1.01,1.4,1.6,1.7,2.01]

# round t2 values to the nearest half
new_t2 = [round(num * 2)/2 for num in t2]

# set y2 values
y2 = [3*z for z in new_t2]

# eliminate entries that have the same index value
for x in range(1, len(new_t2), -1):
    if new_t2[x] == new_t2[x-1]:
        new_t2.delete(x)
        y2.delete(x)


ser1 = pd.Series(y1, index=t1)
ser2 = pd.Series(y2, index=new_t2)

df = pd.concat((ser1, ser2), axis=1)
df.columns = ('Y1', 'Y2')

print df

打印:

      Y1   Y2
0.0  0.0  0.0
0.5  0.5  1.5
1.0  1.0  3.0
1.5  1.5  4.5
1.5  1.5  4.5
1.5  1.5  4.5
2.0  2.0  6.0