2017-02-01 113 views
1

我是編程新手。我遇到了這個要求。我有一個數組,如何根據數組的兩個日期添加列值?

data= ['2016-1-01', '2016-1-08', '2016-1-15', '2016-1-22', '2016-1-29', '2016-02-05', '2016-02-12', '2016-02-19', '2016-02-26'] 

我有查詢結果如下:

date   a  b  c 
2016-01-19 3  1  5 
2016-01-20 10  4  5 
2016-01-30 1  4  6 

我想生成每週報告的數據。

在本示例中,日期'2016-01-19'和'2016-01-20'位於數據數組的「2016-01-15」和「2016-01-22」之間,因此a, b要加上c & c。

最終的輸出應該是這樣的:

2016-1-01  0  0  0 
2016-1-08  0  0  0 
2016-1-15  13  5  10 
2016-1-22  0  0  0 
2016-1-29  1  4  6 
2016-2-05  0  0  0 
2016-2-12  0  0  0 
2016-2-19  0  0  0 
2016-2-26  0  0  0 
+0

查詢結果在哪裏?在一個文件中,一個字符串,一個列表? – jdehesa

+0

我已經存儲瞭如下查詢結果: [(datetime.date(2016,1,19),3,1,5), (datetime.date(2016 ,1,20),10,4,5), (datetime.date(2016,1,30),1,4,6)] – nas

回答

1

這是一個假設data是有序的,否則使用sorted(data)

import datetime 

data = [ 
    '2016-1-01', '2016-1-08', '2016-1-15', 
    '2016-1-22', '2016-1-29', '2016-02-05', 
    '2016-02-12', '2016-02-19', '2016-02-26' 
] 

query_result = [ 
    (datetime.date(2016, 1, 19), 3, 1, 5), 
    (datetime.date(2016, 1, 20), 10, 4, 5), 
    (datetime.date(2016, 1, 30), 1, 4, 6) 
] 

# Convert string dates to datetime.date 
date_data = [ datetime.datetime.strptime(date, '%Y-%m-%d').date() 
       for date in data ] 

res = [] 
# zip the dates together in pairs 
for start, end in zip(date_data, date_data[1:]): 
    tally_a = tally_b = tally_c = 0 
    for date, a, b, c in query_result: 
     # if date is in between add values 
     if start <= date <= end: 
      tally_a += a 
      tally_b += b 
      tally_c += c 

    res.append((start, tally_a, tally_b, tally_c)) 

# Output 
for d, a, b, c in res: 
    print(d, a, b, c, sep = '\t') 

2016-01-01 0 0 0 
2016-01-08 0 0 0 
2016-01-15 13 5 10 
2016-01-22 0 0 0 
2016-01-29 1 4 6 
2016-02-05 0 0 0 
2016-02-12 0 0 0 
2016-02-19 0 0 0 
+0

謝謝@Steven Summers – nas

+1

不客氣。如果你有很大的查詢結果,那麼你可能希望在找到一個匹配來優化過程後去除它們。 –

2

假設data總是排序,沒有重複的元素(你可以做data = sorted(set(data))如果不是這樣),你可以做這樣的事情:

import datetime 

data = ['2016-1-01', '2016-1-08', '2016-1-15', '2016-1-22', '2016-1-29', '2016-02-05', '2016-02-12', '2016-02-19', '2016-02-26'] 
query = [(datetime.date(2016, 1, 19), 3, 1, 5), (datetime.date(2016, 1, 20), 10, 4, 5), (datetime.date(2016, 1, 30), 1, 4, 6)] 

# Convert data to datetime objects 
data = [datetime.datetime.strptime(d, '%Y-%m-%d').date() for d in data] 

output = [] 
query_it = iter(query) 
next_date = data[0] 
next_nums = (0, 0, 0) 
# Iterate through date ranges 
for d_start, d_end in zip(data, data[1:] + [datetime.date.max]): 
    # If the next interesting date is in range 
    if next_date < d_end: 
     nums = next_nums 
     next_nums = (0, 0, 0) 
     for q in query_it: 
      q_date, q_nums = q[0], q[1:] 
      if q_date < d_start: 
       # Ignore dates before the first date in data 
       continue 
      elif q_date < d_end: 
       # Add query numbers to count if in range 
       nums = tuple(n1 + n2 for n1, n2 in zip(nums, q_nums)) 
      else: 
       # When out of range save numbers for next 
       next_date = q_date 
       next_nums = q_nums 
       break 
    else: 
     # Default to zero when no query dates in range 
     nums = (0, 0, 0) 
    # Add result to output 
    output.append((d_start,) + nums) 

for out in output: 
    print(out) 

輸出:

(datetime.date(2016, 1, 1), 0, 0, 0) 
(datetime.date(2016, 1, 8), 0, 0, 0) 
(datetime.date(2016, 1, 15), 13, 5, 10) 
(datetime.date(2016, 1, 22), 0, 0, 0) 
(datetime.date(2016, 1, 29), 1, 4, 6) 
(datetime.date(2016, 2, 5), 0, 0, 0) 
(datetime.date(2016, 2, 12), 0, 0, 0) 
(datetime.date(2016, 2, 19), 0, 0, 0) 
(datetime.date(2016, 2, 26), 0, 0, 0) 
+0

謝謝@jdehesa – nas

+1

@nas沒問題:)無意批評,但只是爲了指出我的解決方案和Steven的區別。他更簡單,更具可讀性和可維護性; mine有點複雜,但只能遍歷查詢結果一次(而Steven的解決方案會遍歷數據中的每個值)。如果查詢結果不是很大,那麼可能並不重要,但如果它可能會影響性能。 – jdehesa