基于时间戳连续性在熊猫中拆分数据帧

时间:2018-09-11 11:06:04

标签: python pandas dataframe split

我想创建一个新的DataFrame,它由对应于最后一列中值1.0或NaN的行组成,因此我只将Nans设置为1.0。但是,我也想考虑结果0.0的行,只要最多有两个这样的时间戳记(例如,在下面的简单示例中,我将选择时间戳记为00-00-30和00-00的行) -40)。

Timestamp  Value         Result    
00-00-10   34567          1.0  
00-00-20   45425     
00-00-30   46773          0.0  
00-00-40   64567   
00-00-50   25665          1.0  
00-01-00   25678  
00-01-10   84358 
00-01-20   76869          0.0
00-01-30   95830          
00-01-40   87890        
00-01-50   99537            
00-02-00   85957          1.0
00-02-10   58840    

我将其分为两个数据帧:

df_1 = data[((data['Result'].isnull()) & data['Result'].ffill() == 1) | data.Result == 1]

df_2 = data[((data['Result'].isnull()) & data['Result'].ffill() == 0) | data.Result == 0]

如何将df_2分成多个块,以使时间戳连续/不间断? (然后,我可以检查每个块是否大于允许的长度,如果不是,则将其附加到df_1上并根据时间对其进行排序。)

因此,我需要输出:

Timestamp  Value         Result    
00-00-10   34567          1.0  
00-00-20   45425     
00-00-30   46773          0.0  
00-00-40   64567   
00-00-50   25665          1.0  
00-01-00   25678  
00-01-10   84358 
00-02-00   85957          1.0
00-02-10   58840    

2 个答案:

答案 0 :(得分:0)

示例数据:

df = pd.DataFrame({'Timestamp': ['00-00-10', '00-00-20', '00-00-30', '00-00-40', 
                   '00-00-50', '00-01-00', '00-01-10', '00-01-20', 
                   '00-01-30', '00-01-40', '00-01-50', '00-02-00', 
                   '00-02-10'],
      'Value': range(0, 13),
      'Result': [1.0, None, 0.0, None, 1.0, None, None, 0.0, None, None, None, 1.0, None]})

代码:

#where NaN after 1
df1 = df.shift(-1)[df.Result == 1] 
#where 1
df2 = df[df.Result==1]
#index where 0 with max Timestamp
ind = df[df.Timestamp == min(df[df.Result == 0].Timestamp)[df.Result==0].index[0]
#select by ind and one next
df3 = df.loc[[ind, ind+1]]

输出:

    Result Timestamp  Value
0      NaN  00-00-20    1.0
4      NaN  00-01-00    5.0
11     NaN  00-02-10   12.0
0      1.0  00-00-10    0.0
4      1.0  00-00-50    4.0
11     1.0  00-02-00   11.0
2      0.0  00-00-30    2.0
3      NaN  00-00-40    3.0

然后,您可以根据需要对索引进行排序。 希望对您有所帮助。但是我不确定我是否了解您的最后选择。 而且我不明白为什么您的原始结果为“ 00-01-10”。

答案 1 :(得分:0)

只需制作一个满足所有三个条件的mask,然后对原始DataFrame进行子集

mask = (
        (df.Result == 1) 
        | (df.Result.ffill() == 1)
        | ((df.Result.ffill() == 0) 
           & (df.groupby((df.Result.ffill() != df.Result.ffill().shift()).cumsum()).Result.transform('size') <= 2))
       )

输出:df[mask]

   Timestamp  Value  Result
0   00-00-10  34567     1.0
1   00-00-20  45425     NaN
2   00-00-30  46773     0.0
3   00-00-40  64567     NaN
4   00-00-50  25665     1.0
5   00-01-00  25678     NaN
6   00-01-10  84358     NaN
11  00-02-00  85957     1.0
12  00-02-10  58840     NaN

说明: 你有三个条件

  1. 如果结果== 1,请保留
  2. 如果它是低于结果== 1(用.ffill()完成的Nan),请保持
  3. 第三个条件确定了连续组的大小,如果是连续0组且大小为<= 2的情况,我们将保持不变