2013-07-25 34 views
5

Tôi có danh sách các danh sách chứa các mục [yyyy, value], với mỗi danh sách phụ được sắp xếp theo năm tăng dần. Dưới đây là một ví dụ:Chèn ngày bị thiếu trong khi giữ thứ tự ngày trong danh sách python

A = [ 
    [[2008, 5], [2009, 5], [2010, 2], [2011, 5], [2013, 17]], 
    [[2008, 6], [2009, 3], [2011, 1], [2013, 6]], [[2013, 9]], 
    [[2008, 4], [2011, 1], [2013, 4]], 
    [[2010, 3], [2011, 3], [2013, 1]], 
    [[2008, 2], [2011, 4], [2013, 1]], 
    [[2009, 1], [2010, 1], [2011, 3], [2013, 3]], 
    [[2010, 1], [2011, 1], [2013, 5]], 
    [[2011, 1], [2013, 4]], 
    [[2009, 1], [2013, 4]], 
    [[2008, 1], [2013, 3]], 
    [[2009, 1], [2013, 2]], 
    [[2013, 2]], 
    [[2011, 1], [2013, 1]], 
    [[2013, 1]], 
    [[2013, 1]], 
    [[2011, 1]], 
    [[2011, 1]] 
    ] 

Những gì tôi cần là để chèn tất cả các năm mất tích giữa min (năm) và max (năm) và để đảm bảo rằng thứ tự được bảo tồn. Vì vậy, ví dụ, lấy sublist đầu tiên của A:

[2008, 5], [2009, 5], [2010, 2], [2011, 5], [2013, 17] 

nên hình như:

[min_year, 0]...[2008, 5], [2009, 5], [2010, 2], [2011, 5], [2012, 0],[2013, 17],..[max_year, 0] 

Hơn nữa, nếu có sublist chỉ chứa một mục duy nhất sau đó quá trình tương tự cần được áp dụng để nó sao cho giá trị ban đầu giữ nguyên thứ tự được giả định và phần còn lại của các mục từ min đến tối đa (năm, giá trị) được chèn đúng cách.

Bất kỳ ý tưởng nào?

Cảm ơn.

Trả lời

3
minyear = 2008 
maxyear = 2013 
new_a = [] 
for group in A: 
    group = group 
    years = [point[0] for point in group] 
    print years 
    for year in range(minyear,maxyear+1): 
     if year not in years: 
      group.append([year,0]) 
    new_a.append(sorted(group)) 
print new_a 

này tạo ra:

[ [[2008, 5], [2009, 5], [2010, 2], [2011, 5], [2012, 0], [2013, 17]], 
    [[2008, 6], [2009, 3], [2010, 0], [2011, 1], [2012, 0], [2013, 6]], 
    [[2008, 0], [2009, 0], [2010, 0], [2011, 0], [2012, 0], [2013, 9]], 
    [[2008, 4], [2009, 0], [2010, 0], [2011, 1], [2012, 0], [2013, 4]], 
    [[2008, 0], [2009, 0], [2010, 3], [2011, 3], [2012, 0], [2013, 1]], 
    [[2008, 2], [2009, 0], [2010, 0], [2011, 4], [2012, 0], [2013, 1]], 
    [[2008, 0], [2009, 1], [2010, 1], [2011, 3], [2012, 0], [2013, 3]], 
    [[2008, 0], [2009, 0], [2010, 1], [2011, 1], [2012, 0], [2013, 5]], 
    [[2008, 0], [2009, 0], [2010, 0], [2011, 1], [2012, 0], [2013, 4]], 
    [[2008, 0], [2009, 1], [2010, 0], [2011, 0], [2012, 0], [2013, 4]], 
    [[2008, 1], [2009, 0], [2010, 0], [2011, 0], [2012, 0], [2013, 3]], 
    [[2008, 0], [2009, 1], [2010, 0], [2011, 0], [2012, 0], [2013, 2]], 
    [[2008, 0], [2009, 0], [2010, 0], [2011, 0], [2012, 0], [2013, 2]], 
    [[2008, 0], [2009, 0], [2010, 0], [2011, 1], [2012, 0], [2013, 1]], 
    [[2008, 0], [2009, 0], [2010, 0], [2011, 0], [2012, 0], [2013, 1]], 
    [[2008, 0], [2009, 0], [2010, 0], [2011, 0], [2012, 0], [2013, 1]], 
    [[2008, 0], [2009, 0], [2010, 0], [2011, 1], [2012, 0], [2013, 0]], 
    [[2008, 0], [2009, 0], [2010, 0], [2011, 1], [2012, 0], [2013, 0]]] 
+0

Cảm ơn @ tehsockz..này đã hoạt động. hoàn hảo. – user2480542

3

Làm thế nào về:

import numpy as np 

def np_fill(data,min_year,max_year): 

    #Setup empty array 
    year_range=np.arange(min_year,max_year+1) 
    unit=np.dstack((year_range,np.zeros(max_year-min_year+1))) 
    overall=np.tile(unit,(len(data),1,1)).astype(np.int) 

    #Change the list to a list of ndarrays 
    data=map(np.array,data) 

    for num,line in enumerate(data): 

     #Find correct indices and update overall array 
     index=np.searchsorted(year_range,line[:,0]) 
     overall[num,index,1]=line[:,1] 
    return overall 

Run mã:

print np_fill(A,2008,2013)[:2] 

[[[2008 5] 
    [2009 5] 
    [2010 2] 
    [2011 5] 
    [2012 0] 
    [2013 17]] 

[[2008 6] 
    [2009 3] 
    [2010 0] 
    [2011 1] 
    [2012 0] 
    [2013 6]]] 


print np_fill(A,2008,2013).shape 
(18, 6, 2) 

Bạn có một bản sao cho năm 2013 trong dòng thứ hai của A, không chắc chắn nếu điều này là có mục đích hay không.

Một vài thời gian vì tôi tò mò, mã nguồn có thể được tìm thấy here. Vui lòng cho tôi biết nếu bạn tìm thấy lỗi.

Đối với đầu năm/cuối năm (2008,2013):

np_fill took 0.0454630851746 seconds. 
tehsockz_fill took 0.00737619400024 seconds. 
zeke_fill_fill took 0.0146050453186 seconds. 

Loại mong this- phải mất rất nhiều thời gian để chuyển đổi sang NumPy mảng. Đối với phá vỡ thậm chí có vẻ như khoảng thời gian những năm cần phải được khoảng 30:

Đối đầu năm/cuối năm (1985,2013):

np_fill took 0.049400806427 seconds. 
tehsockz_fill took 0.0425939559937 seconds. 
zeke_fill_fill took 0.0748357772827 seconds. 

NumPy tất nhiên không dần dần tốt hơn từ đó. Nếu bạn cần trả về một mảng numpy vì bất kỳ lý do gì, thuật toán gọn gàng luôn luôn nhanh hơn.

+0

tuyệt vời, thưa bạn. Rất nhiều đánh giá cao. Tốt của nó để xem một cách numpythonic xung quanh. Cảm ơn :-) – user2480542

2

Ở đây bạn đi, hy vọng bạn thích nó!

min_year = 2007 # for testing purposes I used these years 
max_year = 2014 

final_list = [] # you're going to be adding to this list the corrected values 

for outer in A: # start by iterating through each outer list in A 
    active_years = {} # use this dictionary to keep track of which years are in each list and their values; sorry if you don't know about dictionaries 

    for inner in outer: # now iterate through each year in each of the outer lists and create a dictionary entry for each (print to see what it's doing) 
     active_years[inner[0]] = inner[1] # see who I'm creating a new key-value pair with the key as the year given by the 0th index of inner 

    new_outer = [] # this will be your new outer list 
    for year in range(min_year, max_year + 1): # now add to your active_years dictionary all the other years and give them value 0 
     if year not in active_years.keys(): # only add the years not in your dictionary already 
      active_years[year] = 0 

    for entry in active_years.keys(): # we now iterate through each key, in order 
     new_outer += [[entry, active_years[entry]]] # create your new outer list, watch carefully the brackets 
    final_list += [new_outer] # add to the final_list 

print final_list # presto 
Các vấn đề liên quan