Разделение фреймов данных на основе непрерывности меток времени в Pandas - PullRequest
0 голосов
/ 11 сентября 2018

Я хочу создать новый 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 голосов
/ 11 сентября 2018

Просто создайте 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())
  3. Третье условие определяетразмер последовательных групп, и мы сохраняем, если это последовательная группа 0 с размером <= 2
0 голосов
/ 11 сентября 2018

Пример данных:

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" в результате.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...