Выполните итерацию по набору данных и найдите индексы строк в R или Python - PullRequest
1 голос
/ 01 марта 2020

Цель

У меня большой набор данных, df, где у меня есть столбцы длины, даты и редактирования. Моя цель - перебрать большой набор данных и найти индекс, время начала и окончания для заданного условия.

Работа в обратном направлении , мне нужно получить индекс или номер строки , где значение Edit равно False * с условием, что предыдущий Правка истина . Это выведет «Конец» и значение в столбце Длина.

Начало генерируется возвращаясь назад от индекса «Конец» («Изменить» - «Ложь» ) и когда вы встречаете следующую («Редактировать - Ложь») + 1

 Length        Date                               Edit

  20            1/2/2020 1:00:00 AM               False
  21            1/2/2020 1:00:01 AM               True
  81            1/2/2020 1:00:02 AM               True
  81            1/2/2020 1:00:03 AM               True
  90            1/2/2020 1:00:04 AM               False
  20            1/2/2020 1:00:05 AM               True
  90            1/2/2020 1:00:06 AM               True
  81            1/2/2020 1:00:10 AM               True
  90            1/2/2020 1:00:15 AM               False        
  20            1/2/2020 1:00:25 AM               True

Это мой желаемый вывод:

Start                   End                   Duration   RowNum      Length 

1/2/2020 1:00:05 AM     1/2/2020 1:00:15 AM   10         8              90
1/2/2020 1:00:01 AM     1/2/2020 1:00:04 AM   3          4              90

Начиная назад , мы видим, что время первого окончания - 1/2/2020 1:00:15, потому что Edit имеет значение False, а предыдущее значение Edit равно True. Длина - 90, а RowNumber - 8. Старт будет go в обратном направлении с 1/2/2020 1:00:15 до тех пор, пока мы не придем к , еще одно правка - ложная линия плюс 1 , поэтому будет: 1/2/2020 1:00:05

dput

structure(list(Length = c(20L, 21L, 81L, 81L, 90L, 20L, 90L, 
81L, 90L, 20L), Date = structure(1:10, .Label = c("1/2/2020 1:00:00 AM", 
"1/2/2020 1:00:01 AM", "1/2/2020 1:00:02 AM", "1/2/2020 1:00:03 AM", 
"1/2/2020 1:00:04 AM", "1/2/2020 1:00:05 AM", "1/2/2020 1:00:06 AM", 
"1/2/2020 1:00:10 AM", "1/2/2020 1:00:15 AM", "1/2/2020 1:00:25 AM"
 ), class = "factor"), Edit = c(FALSE, TRUE, TRUE, TRUE, FALSE, 
TRUE, TRUE, TRUE, FALSE, TRUE)), class = "data.frame", row.names = c(NA, 
-10L))

Это то, что я пробовал

 library(dplyr)
 library(readr)

 for (i in 1:nrow(df) {


if (df[i] == Edit == "False") {
print(df[rows]) 
}
    else if (df[i] < condition) {
print(df[rows])

}
    }

   mutate(Date = as.POSIXct(Date, format = '%m/%d/%Y %H:%M:%OS')) %>%
   mutate(RowNum = cumsum(!cond)) %>%
   group_by(Length) %>%
   summarize(Start = min(Date),
        End = max(Date),
        Duration = End - Start) %>%

У меня есть начало, я просто не уверен, как это собрать. Любая помощь или предложения приветствуются.

Ответы [ 3 ]

2 голосов
/ 01 марта 2020

True + False должен давать 1 (True == 1, False == 0). По сути, один конец должен быть True + False, другой конец должен быть False + True. Итак, у вас есть окно.
Следующим шагом является избавление от пустых значений. Затем ищите значения вражение_переход, равные 1.

df['grouping_forward'] = df.Edit.add(df.Edit.shift(1))
df['grouping_backward'] = df.Edit.add(df.Edit.shift(-1))


(df.dropna()
 .query('grouping_forward==1')
 .assign(Row = lambda x: np.where(x.Edit.eq(0),
                                  x.index,
                                  np.nan),
        Start = lambda x: np.where(x.Edit.eq(1), 
                                   x.Date,
                                   np.datetime64('NaT')),
        End = lambda x: np.where(x.Edit.eq(0),
                                 x.Date,
                                 np.datetime64('NaT'))
    )
 .ffill()
 .query('Edit == 0')
 .drop(['grouping_forward','grouping_backward','Date','Edit'],axis=1)
 .assign(Duration = lambda x: x.End.sub(x.Start).dt.seconds)
  )

    Length  Row     Start                End             Duration
4   90      4.0 2020-01-02 01:00:01 2020-01-02 01:00:04     3
8   90      8.0 2020-01-02 01:00:05 2020-01-02 01:00:15     10
0 голосов
/ 01 марта 2020

Использование dplyr:

library(dplyr)

df %>%
  mutate(Date = lubridate::mdy_hms(Date),
         gr = lag(cumsum(!Edit), default = TRUE)) %>%
  slice(-c(1, n())) %>%
  group_by(gr) %>%
  summarise(Start = min(Date),
            End = max(Date),
            Duration = as.integer(End - Start), 
            RowNum = n(), 
            Length = Length[n()]) %>%
  mutate(RowNum = cumsum(RowNum)) %>%
  slice(n():1) %>%
  select(-gr)

#  Start               End                 Duration RowNum Length
#  <dttm>              <dttm>                 <int>  <int>  <int>
#1 2020-01-02 01:00:05 2020-01-02 01:00:15       10      8     90
#2 2020-01-02 01:00:01 2020-01-02 01:00:04        3      4     90
0 голосов
/ 01 марта 2020

Если вы используете Pandas, вы можете обратиться к этому вопросу Как перебирать строки в DataFrame в Pandas?

Индекс, где находится строка, вероятно срез строки, на который вы ссылались? и строка, очевидно, строка. Вы можете выбрать поле данных в строке, которая вас интересует.

для поля данных 'Редактировать', когда вы l oop просматриваете набор данных, вы можете написать что-то вроде:

for index, row in df.iterrows():
    if row['Edit'] == 'False'
        print(index) #where the row is
...