【问题标题】:Python pandas resamplingPython熊猫重采样
【发布时间】:2015-11-24 16:18:01
【问题描述】:

我有以下数据框:

    Timestamp    S_time1   S_time2   End_Time_1   End_time_2   Sign_1   Sign_2
0    2413044       0        0           0            0          x        x
1    2422476       0        0           0            0          x        x
2    2431908       0        0           0            0          x        x
3    2441341       0        0           0            0          x        x
4    2541232   2526631   2528631     2520631      2530631      10       80
5    2560273   2544946   2546496     2546496      2548496      40       80
6    2577224   2564010   2566010     2566010      2568010     null    null
7    2592905   2580959   2582959     2582959      2584959     null    null

桌子就这样继续下去。第一列是以毫秒为单位的时间戳。 S_time1End_time_1 是特定符号(数字)出现的持续时间。例如,如果我们取第 5 行,S_time1 是 2526631,End_time_1 是 2520631,对应的sign_1 是 10,这意味着从 2526631 到 2520631 将显示符号 10。 S_time2End_time_2 也是如此。 sign_2中对应的值会出现在S_time2End_time_2的持续时间内。

我想在 100 毫秒的 bin 时间内对索引列 (Timestamp) 重新采样,并检查符号所属的 bin 时间。例如,每个开始时间和结束时间之间有 2000 毫秒的差异。因此,相应的符号编号将在大约 20 个连续的 bin 时间中重复出现,因为每个 bin 时间是 100 毫秒。所以我只需要两列:一列是 bin 时间,第二列是标志。如下表所示:(我只是补个bin时间为例)

Bin_time   signs
...100        0
...200        0
...300        10
...400        10
...500        10
...600        10

符号 10 将持续对应的 S_time1 到 End_time_1。然后下一个符号 80 持续 S_time2 到 End_time_2 的持续时间。我不确定这是否可以在熊猫中完成。但我真的需要熊猫或其他方法的帮助。

提前感谢您的帮助和建议。

【问题讨论】:

  • 我认为您最好将所有列中的时间戳视为整数。我想到的原因是这些似乎是对某个事件进行倒计时的纪元时间,将它们转换为时间戳只会延长您的代码。此外,您只对相对值感兴趣,而不是绝对值。时间戳也更难使用,并且开销更大。我的个人经验也表明pd.resample() 可能不适合你。所以,只需使用直方图函数,或者编写自己的函数来得到你想要的。

标签: python python-2.7 pandas


【解决方案1】:

输入:

print df
  Timestamp  S_time1  S_time2  End_Time_1  End_time_2 Sign_1 Sign_2
0    2413044        0        0           0           0      x      x
1    2422476        0        0           0           0      x      x
2    2431908        0        0           0           0      x      x
3    2441341        0        0           0           0      x      x
4    2541232  2526631  2528631     2520631     2530631     10     80
5    2560273  2544946  2546496     2546496     2548496     40     80
6    2577224  2564010  2566010     2566010     2568010   null   null
7    2592905  2580959  2582959     2582959     2584959   null   null

2 种方法:

In [231]: %timeit s(df)
1 loops, best of 3: 2.78 s per loop

In [232]: %timeit m(df)
1 loops, best of 3: 690 ms per loop
def m(df):
    #resample column Timestamp by 100ms, convert bak to integers 
    df['Timestamp'] = df['Timestamp'].astype('timedelta64[ms]')
    df['i'] = 1
    df = df.set_index('Timestamp')
    df1 = df[[]].resample('100ms', how='first').reset_index()
    df1['Timestamp'] = (df1['Timestamp'] / np.timedelta64(1, 'ms')).astype(int)
    #felper column i for merging
    df1['i'] = 1
    #print df1

    out = df1.merge(df,on='i', how='left')
    out1 = out[['Timestamp', 'Sign_1']][(out.Timestamp >= out.S_time1) & (out.Timestamp <= out.End_Time_1)]
    out2 = out[['Timestamp', 'Sign_2']][(out.Timestamp >= out.S_time2) & (out.Timestamp <= out.End_time_2)]

    out1 = out1.rename(columns={'Sign_1':'Bin_time'})
    out2 = out2.rename(columns={'Sign_2':'Bin_time'})

    df = pd.concat([out1, out2], ignore_index=True).drop_duplicates(subset='Timestamp')
    df1 = df1.set_index('Timestamp')
    df = df.set_index('Timestamp')
    df = df.reindex(df1.index).reset_index()
    #print df.head(10)
def s(df):
    #resample column Timestamp by 100ms, convert bak to integers 
    df['Timestamp'] = df['Timestamp'].astype('timedelta64[ms]')
    df = df.set_index('Timestamp')
    out = df[[]].resample('100ms', how='first')
    out = out.reset_index()
    out['Timestamp'] = (out['Timestamp'] / np.timedelta64(1, 'ms')).astype(int)
    #print out.head(10)

    #search start end 
    def search(x):
        mask1 = (df.S_time1<=x['Timestamp']) & (df.End_Time_1>=x['Timestamp'])
        #if at least one True return first value of series
        if mask1.any():
                return df.loc[mask1].Sign_1[0]
        #check second start and end time
        else:
                mask2 = (df.S_time2<=x['Timestamp']) & (df.End_time_2>=x['Timestamp'])
                if mask2.any():
                    #if at least one True return first value
                    return df.loc[mask2].Sign_2[0]
                else:
                    #if all False return NaN
                    return np.nan

    out['Bin_time'] = out.apply(search, axis=1)
    #print out.head(10)

【讨论】:

  • 您已使用 S_time1、end_time_1、S_time2 和 end_time_2 作为 bin 时间。但我想使用第一列('Timestamp')作为重采样列(bin time)。并检查开始时间和结束时间在 bin 时间中从哪里到哪里,并相应地填写标志。如果这有意义的话。
猜你喜欢
  • 1970-01-01
  • 2016-11-25
  • 1970-01-01
  • 2021-06-01
  • 2013-06-04
  • 2015-11-21
  • 2017-10-09
  • 2022-06-10
  • 2017-02-20
相关资源
最近更新 更多