在Python中,在列之间减去日期,条件是只减去同一年内的日期
因此,我正在进行一个项目,需要确定多个设备启动指标。为了确定发布指标,我需要一行代码来搜索序列中的唯一日期列表,并减去具有相同年份的日期。因此,如果SV_日期为2015/03/05,代码将通过系列“发布日期”查找该年的匹配项(例如2015/06/22),然后减去日期。函数的作用是:检查结果是否在0到30天的范围内,并返回一个布尔值。最后,如果为True,则astype(int)返回1 当我运行代码时,我遇到两条错误消息。第一个错误和真值不明确有关,因为我比较了两列在Python中,在列之间减去日期,条件是只减去同一年内的日期,python,r,pandas,function,datetime,Python,R,Pandas,Function,Datetime,因此,我正在进行一个项目,需要确定多个设备启动指标。为了确定发布指标,我需要一行代码来搜索序列中的唯一日期列表,并减去具有相同年份的日期。因此,如果SV_日期为2015/03/05,代码将通过系列“发布日期”查找该年的匹配项(例如2015/06/22),然后减去日期。函数的作用是:检查结果是否在0到30天的范围内,并返回一个布尔值。最后,如果为True,则astype(int)返回1 当我运行代码时,我遇到两条错误消息。第一个错误和真值不明确有关,因为我比较了两列 def day_diff(en
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'],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')).unique()).between(0,30).astype(int)
如果我不想比较两列之间的年份,那么这段代码就足够了:
data['AL030'] = day_diff(data['SV_DATE'],data_2.loc[(data_2['MFG'] == 'APPLE'), 'Launch Date']).between(0,60).astype(int)
最后,我尝试在R中优化这段代码,以返回相同的值,而不使用类似于launch.ind one的函数,同时双重添加年份条件以减少运行时间:
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, 1, 0)
}
return(y)
}
###############################
# Add launch indicators
data$AL030 = launch.ind(data$SV_DATE,unique(data_2$"Launch Date"[toupper(data_2$MFG)=="APPLE"]),0,30)
day_diff=功能(结束、开始){
x=difftime(结束、开始,单位=c(“天”)
返回(x)
}
launch.ind=功能(发货日期、发货日期、低位、高位){
y=代表(0,长度(数据$SV_日期))
对于(i,长度(数据$SV_日期))){
y[i]=总和(如果其他((日差(发货日期[i],下水日期)>=低)和(日差(发货日期[i],下水日期)0,1,0)
}
返回(y)
}
###############################
#添加启动指示器
数据$AL030=launch.ind(数据$SV_DATE,唯一(数据$2$“launch DATE”[toupper(数据$MFG)==“APPLE”]),0,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
的行),按年份合并两个数据帧,按年份计算日期之间的差异,然后验证它们是否在所需范围内(0,30)
:
输出:
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
我想,通过这个输出,您可以做任何您想做的事情。请注意,我保留了一个索引列,以便在data\u 1
中检索这些行
R
使用R的类似方法:
library(dplyr)
# Fake data
data_1 <- data.frame(SV_DATE = as.Date(c('2015/03/05', '2015/03/10', '2016/01/01')))
data_2 <- data.frame (
Launch_Date = as.Date(c('2015/03/05', '2015/12/01', '2016/01/01', '2017/01/01')),
MFG = c('APPLE', 'WINDOWS', '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, 0, 30))
笔记
虽然这段代码适用于我提供的虚假数据,但它可能不适用于您。无论如何,我相信它提供了一些通过修改来实现您的目标的方法 另外,请注意,我在两个代码块中将
保留为布尔值,但您可以分别使用Python和R中的.astype(int)
和as.integer(…)
将其更改为整数。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
的行),按年份合并两个数据帧,按年份计算日期之间的差异,然后验证它们是否在所需范围内(0,30)
:
输出:
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
我想,通过这个输出,您可以做任何您想做的事情。请注意,我保留了一个索引列,以便在data\u 1
中检索这些行
R
使用R的类似方法:
library(dplyr)
# Fake data
data_1 <- data.frame(SV_DATE = as.Date(c('2015/03/05', '2015/03/10', '2016/01/01')))
data_2 <- data.frame (
Launch_Date = as.Date(c('2015/03/05', '2015/12/01', '2016/01/01', '2017/01/01')),
MFG = c('APPLE', 'WINDOWS', '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, 0, 30))
笔记
虽然这段代码适用于我提供的虚假数据,但它可能不适用于您。无论如何,我相信它提供了一些通过修改来实现您的目标的方法
另外,请注意,我在两个代码块中将保留为布尔值,但您可以使用.astype(int)
和将其更改为整数(…)
分别在Python和R中使用。请发布数据和数据2
的示例。请参见。除此之外,比较不同数据帧中的列几乎不是一个好主意。尝试合并,然后运行条件逻辑。在R代码中,向量中有多少值是唯一的(data_2$“Launch Date”[toupper(data_2$MFG)=“APPLE”]
?它应该是一个或,否则
会因长度不同而引发错误。实际上,R和Pandas代码不一致。R不是返回天数,而是在低阈值和高阈值之间(即0到30天之间)满足条件的次数。请发布数据
和数据2
的示例。请参阅。除此之外,比较不同数据帧中的列几乎不是一个好主意。尝试合并,然后运行条件逻辑。在R代码中,向量中有多少值是唯一的(data_2$“Launch Date”[toupper(data_2$MFG)=“APPLE”]
?它应该是一个或,否则
将因长度不同而引发错误。实际上,R和Pandas代码不一致。R不是返回天数,而是在低阈值和高阈值之间(即0到30天之间)满足条件的次数。