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

мой фрейм данных выглядит следующим образом:

Short View of Data

Элемент в PlantProduct (означает завод);может иметь несколько номеров материалов Что я хочу сделать:

  1. Сгруппировать фрейм данных по PlantProduct и MaterialNumber, другими словами, разделить их на фреймы данных.
  2. Если длина элемента члена группы меньше 10, чем отбросить его
  3. Так что в конце работы у меня должен быть вид элементов списка, который содержит только этот видфреймы данных:

grouped data

После получения этого фрейма данных я собираюсь выполнить больше дополнительных операций;такие как графики и прогнозирование временных рядов по всем элементам списка (показано на рисунке -2)

Я сделал следующее:

      df.groupby(by=['PlantProduct','MaterialNumber']).apply(lambda x:len(x)>10)

Однако этот скрипт создаетсгруппированный объект фрейма данных, и я не могу выполнить с ним никаких операций.

, чтобы помочь мне записать свой сценарий здесь, но я должен сделать это и на python, как вы можете догадаться, я неЭксперт по питону.

Мой код R:

#split 1st due to PlantProduct

    mylist <- split(res2, res2$PlantProduct)

#second split due to MaterialNumber

      for(name in names(mylist))
      mylist[[name]] <- split(mylist[[name]], mylist[[name]]["MaterialNumber"])
      mylist[[name]] <- mylist[[name]][sapply(mylist[[name]], function(x) nrow(x)[[1]]) > 10]
    } 

#Encoding 0 values with NA, all over the list elements

    for(name in names(mylist)) {
      for(name2 in names(mylist[[name]]))
      {
        mylist[[name]][[name2]][,4] <- ifelse(mylist[[name]][[name2]][,4] == 0, NA, mylist[[name]][[name2]][,4])
      }
    }

#creating a date index column and joining it with the list element

    for(name in names(mylist)) {
      for(name2 in names(mylist[[name]]))
      {
        mydate <- data.frame(seq(min(as.Date(mylist[[name]][[name2]][,3])), as.Date('2018-05-01'), by = "month"))
        colnames(mydate) <- "ds"
        mylist[[name]][[name2]] <- left_join(mydate, mylist[[name]][[name2]], "ds")
        rm(mydate)
      }
    }

#time series forecasting on individual list elements

    for(name in names(mylist)) {
      for(name2 in names(mylist[[name]]))
      {
      m <- prophet(mylist[[name]][[name2]])
      future <- make_future_dataframe(m, periods = 1, freq = "month")
      forecast <- predict(m, future)
      a <- data.frame(tail(forecast[c('ds', 'yhat', 'yhat_lower', 'yhat_upper')], n = 365))
      a$ds <- as.Date(a$ds, "%Y-%m-%d")
      mylist[[name]][[name2]] <- left_join(a, mylist[[name]][[name2]], "ds")
      rm(m, future, forecast, a)
      }
    }

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Вы можете использовать transform

df=df[df.groupby(['PlantProduct', 'MaterialNumber']).PlantProduct.transform('count')>10]

Test Frame от nixon

df[df.groupby(['a','b']).a.transform('count')>2]
Out[203]: 
   a  b
0  1  2
1  1  2
2  1  2
3  1  3
4  1  3
5  1  3
0 голосов
/ 17 декабря 2018

Чтобы GroupBy и сохранить исходную структуру, вместо этого используйте filter из документации:

Верните копиюDataFrame, исключающий элементы из групп, которые не удовлетворяют булевому критерию, определенному func.

Вместо этого сделайте:

df.groupby(['PlantProduct', 'MaterialNumber']).filter(lambda x: len(x) > 10)

Вот игрушечный пример:

df = pd.DataFrame({'a':[1,1,1,1,1,1,1], 'b':[2,2,2,3,3,3,1]})

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

df.groupby(['a', 'b']).apply(lambda x: len(x) >= 2)

a  b
1  1    False
   2     True
   3     True
dtype: bool

Возвращает набор booleans для каждой группы при применении условия.

Однако, используя filter, результат этого условия будет использоваться для фильтрации исходного кадра данных:

df.groupby(['a', 'b']).filter(lambda x: len(x) >= 2)

   a  b
0  1  2
1  1  2
2  1  2
3  1  3
4  1  3
5  1  3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...