微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

减去列之间的日期,条件是仅减去Python中同一年的日期 Python R 注释

如何解决减去列之间的日期,条件是仅减去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 举报,一经查实,本站将立刻删除。