如何解决减去列之间的日期,条件是仅减去Python中同一年的日期 Python R 注释
因此,我正在一个项目中,我需要确定多个设备启动指示器。为了确定启动指示器,我需要代码行来搜索一系列唯一日期的列表,然后减去具有相同年份的日期。因此,如果SV_DATE为2015/03/05,则代码将通过“启动日期”系列查找年份中的匹配项(例如2015/06/22),然后减去日期。 between()函数检查结果是否在0到30天之间,并返回一个布尔值。最后,如果true,则astype(int)返回1
运行代码时,我遇到两条错误消息。第一个错误与由于我比较两列而导致真值不明确有关。
def day_diff(end,start):
ed = pd.to_datetime(end)
sd = pd.to_datetime(start)
#if ed.dt.year == sd.year:
return (ed-sd).dt.days
data['AL030'] = day_diff(data['SV_DATE'],data_2.loc[(data_2['MFG'] == 'APPLE') & (pd.Series(pd.DatetimeIndex(data_2['Launch Date'])).dt.year == pd.Series(pd.DatetimeIndex(data['SV_DATE'])).dt.year),'Launch Date']).between(0,30).astype(int)
为了使代码运行,我需要对年份进行硬编码,而不是让代码搜索日期列。当我这样做时,代码就会起作用。
data['AL030'] = day_diff(data['SV_DATE'],data_2.loc[(data_2['MFG'] == 'APPLE') & (pd.Series(pd.DatetimeIndex(data_2['Launch Date'])).dt.year == 2017),'Launch Date'].apply(lambda x:x.date().strftime('%Y-%m-%d'))).between(0,30).astype(int)
在我甚至向其添加unique()函数之前就遇到了此错误,这给了我一个新错误:'ValueError:无法添加不等长的索引'
data['AL030'] = day_diff(data['SV_DATE'],'Launch Date'].apply(lambda x:x.date().strftime('%Y-%m-%d')).unique()).between(0,30).astype(int)
data['AL030'] = day_diff(data['SV_DATE'],data_2.loc[(data_2['MFG'] == 'APPLE'),60).astype(int)
在一天结束时,我试图优化R中的这段代码以返回相同的值,而无需利用诸如launch.ind这样的函数,同时双重添加年份条件以尝试减少运行时间:
day_diff = function(end,start){
x = difftime(end,start,units=c("days"))
return(x)
}
launch.ind = function(ship.date,launch.date,low,high){
y = rep(0,length(data$SV_DATE))
for (i in seq(length(data$SV_DATE))){
y[i] = sum(ifelse((day_diff(ship.date[i],launch.date)>=low)&(day_diff(ship.date[i],launch.date)<=high),1,0))
y[i] = ifelse(y[i] > 0,0)
}
return(y)
}
###############################
# Add launch indicators
data$AL030 = launch.ind(data$SV_DATE,unique(data_2$"Launch Date"[toupper(data_2$MFG)=="APPLE"]),30)
感谢任何尝试提供帮助的人,我愿意提出建议以帮助澄清所有不清楚的地方
解决方法
Python
假数据:
import pandas as pd
data_1 = pd.DataFrame({
'SV_DATE': pd.to_datetime(['2015/03/05','2015/03/10','2016/01/01'])
})
data_2 = pd.DataFrame({
'Launch Date': pd.to_datetime(['2015/03/05','2015/12/01','2016/01/01','2017/01/01']),'MFG': ['APPLE','WINDOWS','APPLE','WINDOWS']
})
print(data_1)
SV_DATE
0 2015-03-05
1 2015-03-10
2 2016-01-01
print(data_2)
Launch Date MFG
0 2015-03-05 APPLE
1 2015-12-01 WINDOWS
2 2016-01-01 APPLE
3 2017-01-01 WINDOWS
如果我做对了,您可以合并过滤器数据_2(仅包含MFG==APPLE
的行),按年份合并两个数据框,按年份计算日期之间的差异,然后验证它们是否在所需范围内{ 1}}:
(0,30)
输出:
data_1 = data_1.assign(Year = data_1.SV_DATE.dt.year,Index = data_1.index)
data_2 = data_2.assign(Year = data_2['Launch Date'].dt.year).query('MFG=="APPLE"')
data = data_1.merge(data_2,on='Year')
data['Diff'] = data.groupby('Year')[['Launch Date','SV_DATE']].transform('diff',axis=1)['SV_DATE'].dt.days
data['in_target_range'] = data.Diff.between(0,30)
我想,有了这个输出,您可以做任何想做的事情。请注意,如果您愿意,我保留了一个Index列,以便在 SV_DATE Year Index Launch Date MFG Diff in_target_range
0 2015-03-05 2015 0 2015-03-05 APPLE 0 True
1 2015-03-10 2015 1 2015-03-05 APPLE 5 True
2 2016-01-01 2016 2 2016-01-01 APPLE 0 True
中检索这些行。
R
使用R的类似方法:
data_1
输出为:
library(dplyr)
# Fake data
data_1 <- data.frame(SV_DATE = as.Date(c('2015/03/05','2016/01/01')))
data_2 <- data.frame (
Launch_Date = as.Date(c('2015/03/05','2017/01/01')),MFG = c('APPLE','WINDOWS')
)
# Merge and filters
data_2 <- data_2 %>%
mutate(Year = format(Launch_Date,"%Y")) %>%
filter(MFG=="APPLE")
data <- data_1 %>%
mutate(Year = format(SV_DATE,"%Y"),Index = 1:nrow(.)) %>%
inner_join(.,mutate(data_2,Year=format(Launch_Date,"%Y")),by = "Year") %>%
group_by(Year) %>%
mutate(Diff = as.integer(SV_DATE - Launch_Date)) %>%
mutate(in_target_range = between(Diff,30))
我不知道您的# A tibble: 3 x 7
# Groups: Year [2]
SV_DATE Year Index Launch_Date MFG Diff in_target_range
<date> <chr> <int> <date> <chr> <int> <lgl>
1 2015-03-05 2015 1 2015-03-05 APPLE 0 TRUE
2 2015-03-10 2015 2 2015-03-05 APPLE 5 TRUE
3 2016-01-01 2016 3 2016-01-01 APPLE 0 TRUE
函数真正想要什么,但是可能是这样的(?):
launch.ind
注释
尽管此代码适用于我提供的虚假数据,但可能对您不起作用。无论如何,我相信它提供了一些修改目标的方法。
另外,请注意,我在两个代码块中都将low = 0
high = 3
data$AL030 <- data %>%
group_by(SV_DATE) %>%
summarise(launch.ind = sum(ifelse(between(Diff,low,high),1,0)),.groups='drop') %>%
mutate(launch.ind = ifelse(launch.ind > 0,0)) %>%
pull(launch.ind)
保留为布尔值,但是可以分别在Python和R中分别使用in_target_range
和.astype(int)
将其更改为整数。>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。