Skip to main content
 首页 » 编程设计

python从id的日期范围中找到唯一的日期

2025年02月15日4shangdawei

我有 4 天无法解决的问题。我是 python 菜鸟。 我正在使用 python 2.6 在 unix box 上工作......并且没有像 numpy,pandas 这样的额外自由。

我需要做的是尽可能减少以下文件的行数。因此,当同一 id1、id2 的日期范围内的日期相互覆盖时,需要覆盖它们。但是正如您所看到的,期望输出具有最小值和最大值是不够的,因为有些日期不是日复一日。

输入

ID1|IDTYPE2|20160802|20160912| 
ID1|IDTYPE2|20160803|20160913| 
ID1|IDTYPE2|20160804|20160914| 
ID1|IDTYPE2|20160805|20160915|  
ID1|IDTYPE2|20160808|20160916| 
ID1|IDTYPE2|20160925|20160925| 
ID2|IDTYPE2|20160925|20160925| 

预期输出

ID1|IDTYPE2|20160802|20160916| 
ID1|IDTYPE2|20160925|20160925| 
ID2|IDTYPE2|20160925|20160925| 

我已经尝试过,但它给了我很多结果

f = open(filename, 'rU') 
outf = open(filename + '_date_diff', 'w') 
dict_of_ID_dates = defaultdict(list) 
for line in f: 
  columns = line.split("|") 
  ID1 = (columns[0]) 
  IDType2 = (columns[1]) 
  start = (columns[2]) 
  end = (columns[3]) 
  start_date = datetime.datetime.strptime(start,'%Y%m%d').date() 
  end_date = datetime.datetime.strptime(end,'%Y%m%d').date() 
  diff = end_date - start_date 
  list_of_dates =[] 
  date_ranges = range(diff.days +1) 
  # [0,1,2,3] 
  for date in date_ranges: 
    dates = (start_date + datetime.timedelta(date)).isoformat() 
# [datetime format dates = '20160101'] 
    if dates not in dict_of_ID_dates.values(): 
      dict_of_ID_dates[ID].append(dates) 
print (dict_of_ID_dates) 

请您参考如下方法:

假设输入文件 ID 和日期始终按递增顺序排列。下面的代码应该可以工作。

tmpline 充当缓冲区保持行,当 ID 更改或 tmpline 缓冲区中的当前行 date1 > date2 时追加到输出(意味着我们需要开始一个新的日期范围)。如果发现当前行中的日期 2 大于缓冲区中的日期 2,则缓冲区第 2 列 (date2) 将被覆盖。

output = [] 
with open(filename, 'rU') as f: 
    prev_id = None 
    tmpline = '' 
    for line in f: 
        line = line.strip() 
        (id, date1, date2, dummy) = line.rsplit('|', 3) 
        # line = 'ID1|IDTYPE2|20160802|20160912|' 
        # id = 'ID1|IDTYPE2' 
        # date1 = '20160802' 
        # date2 = '20160912' 
        # dummy = '' 
 
        # append to output when new ID changes or  
        # date1 > previous date2 (start new range of dates) 
        if prev_id != id or date1 > tmpline[2]: 
            if tmpline: 
               output.append('|'.join(tmpline)) 
            tmpline = [id, date1, date2, dummy] 
 
        # override end date if larger 
        elif date2 > tmpline[2]: 
            tmpline[2] = date2 
        prev_id = id 
 
    # take care last line 
    tmpline = '|'.join(tmpline) 
    if tmpline != output[-1]: 
        output.append(tmpline) 

输出包含行列表,打印到控制台或写入另一个文件

# print out the ouput 
for line in output: 
    print line 
 
 
# based on the input from the post 
# output = ['ID1|IDTYPE2|20160802|20160916|', 'ID1|IDTYPE2|20160925|20160925|', 'ID2|IDTYPE2|20160925|20160925|']