Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中,在列之间减去日期,条件是只减去同一年内的日期_Python_R_Pandas_Function_Datetime - Fatal编程技术网

在Python中,在列之间减去日期,条件是只减去同一年内的日期

在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

因此,我正在进行一个项目,需要确定多个设备启动指标。为了确定发布指标,我需要一行代码来搜索序列中的唯一日期列表,并减去具有相同年份的日期。因此,如果SV_日期为2015/03/05,代码将通过系列“发布日期”查找该年的匹配项(例如2015/06/22),然后减去日期。函数的作用是:检查结果是否在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'],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天之间)满足条件的次数。