我的数据框如下所示:
PlantProduct中的一个项目(表示植物);可以有多个物料编号
我想做的事:
根据PlantProduct和MaterialNumber对数据框进行分组,换句话说,将它们拆分为数据框。
如果组成员的元素长度小于10,则将其删除
因此,在工作结束时,我应该有一种仅包含此类数据帧的列表元素:
在拥有了这些数据帧之后,我将执行更多的附加操作;例如图表,以及整个列表元素的时间序列预测(如图-2所示)
我所做的事情如下:
df.groupby(by=['PlantProduct','MaterialNumber']).apply(lambda x:len(x)>10)
但是,此脚本创建了一个分组的数据框对象,并且我无法对其执行任何操作。
为了帮助我在这里写下我的脚本,但是我也必须在python中完成它,因为您可能会猜我不是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)
}
}
最佳答案
为了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
关于python - 根据两列拆分数据帧,并对子组应用一些操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53817562/