2 Câu hỏi: Chương trình của tôi hoạt động nhưng rất chậm, nó cũng chậm lại khi chạy

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Tôi đang lấy dữ liệu từ API Kiến thức Học thuật của Microsoft và sau đó sử dụng các phản hồi json làm từ điển để trích xuất thông tin tôi cần. Khi tôi làm điều này, tôi thêm thông tin vào một mảng gọn gàng và cuối cùng tôi thay đổi nó thành một khung dữ liệu gấu trúc để xuất. Chương trình hoạt động tốt, nhưng phải mất một lượng lớn thời gian để chạy. Nó dường như chậm lại khi nó chạy, vì vài lần đầu tiên qua các vòng lặp, chỉ mất vài giây, nhưng sau đó mất vài phút.

Tôi đã cố gắng đơn giản hóa các câu lệnh if khác hết mức có thể và điều này giúp một chút nhưng không đủ để tạo ra sự khác biệt lớn. Tôi cũng đã giảm số lần truy vấn API được thực hiện nhiều nhất có thể. Mỗi truy vấn chỉ có thể trả về 1000 kết quả, nhưng có khoảng 35000 kết quả mà tôi cần.

rel_info = np.array([("Title", "Author_Name", "Jornal_Published_In", "Date")])

for l in range(0, loops):                        # loops is defined above to be 35
    offset = 1000 * l
    # keep track of progress
    print("Progress:" + str(round((offset/total_res)*100, 2)) + "%")
    # get data with request to MAK. 1000 is the max count
    url = "https://api.labs.cognitive.microsoft.com/academic/v1.0/evaluate?expr=And(Composite(AA.AfN=='brigham young university'),Y>=1908)&model=latest&count=1000&offset="+str(offset)+"&attributes=Ti,D,AA.DAfN,AA.DAuN,J.JN"
    response = req.get(url + '&subscription-key={key}')

    data = response.json()

    for i in range(0, len(data["entities"])):
        new_data = data["entities"][i]
        # get new data
        new_title = new_data["Ti"]                 # get title

        if 'J' not in new_data:                    # get journal account for if keys are not in dictionaries
            new_journ = ""
        else:
            new_journ = new_data["J"]["JN"] or ""

        new_date = new_data["D"]                   # get date

        new_auth = ""                              # get authors only affiliated with BYU account for if keys are not in dictionary
        for j in range(0, len(new_data["AA"])):
            if 'DAfN' not in new_data["AA"][j]:
                new_auth = new_auth + ""
            else:
                if new_data["AA"][j]["DAfN"] == "Brigham Young University" and new_auth == "":     # posibly combine conditionals to make less complex
                    new_auth = new_data["AA"][j]["DAuN"]
                elif new_data["AA"][j]["DAfN"] == "Brigham Young University" and new_auth != "":
                    new_auth = new_auth +", "+ new_data["AA"][j]["DAuN"]
        # keep adding new data to whole dataframe
        new_info = np.array([(new_title, new_auth, new_journ, new_date)])
        rel_info = np.vstack((rel_info, new_info))
    
- 1
  1. Vui lòng hiển thị một số Ví dụ tối thiểu, đầy đủ và có thể kiểm chứng trong câu hỏi của bạn
    2019-05-08 16: 09: 05Z
  2. Bạn có biết chính xác nơi xảy ra chậm lại không? Có lẽ API từ xa đang làm phiền bạn và điều chỉnh các yêu cầu của bạn?
    2019-05-08 16: 12: 17Z
  3. Tôi đã quay lại và in một số lần xem nó chạy và tôi thấy rằng sự gia tăng đến từ khi tôi đang sử dụng chức năng vstack từ numpy. Khi mảng trở nên lớn hơn, sẽ mất nhiều thời gian hơn để xếp chồng. Nhưng tôi vẫn không biết làm thế nào để khắc phục điều này vì tôi vẫn cần nối thêm bất kỳ thông tin mới nào tôi trích xuất vào mảng lớn hơn.
    2019-05-08 16: 54: 23Z
  4. Không sử dụng một mảng. Nó không có ý nghĩa trong trường hợp này, có vẻ như bạn đang làm việc với chuỗi? Chỉ cần sử dụng một danh sách bình thường với. chắp thêm, điều đó sẽ cho bạn thời gian tuyến tính, nhưng việc sử dụng một mảng gọn gàng với vstack làm cho thuật toán này trở thành bậc hai
    2019-05-08 17: 05: 14Z
  5. Ý bạn là gì khi "sử dụng gấu trúc để xuất khẩu"? Bạn có thể xây dựng một khung dữ liệu gấu trúc từ một danh sách các danh sách trong mọi trường hợp, nhưng bạn chỉ sử dụng gấu trúc để đổ vào csv?
    2019-05-08 17: 06: 40Z
2 Câu trả lời                              2                         

Hãy thử lấy kết quả trong nhóm luồng công nhân bằng cách sử dụng concurrent.futures như thế này:

import concurrent.futures
import urllib.request

URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/',
        'http://some-made-up-domain.com/']

# Retrieve a single page and report the URL and contents
def load_url(url, timeout):
    with urllib.request.urlopen(url, timeout=timeout) as conn:
        return conn.read()

# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor() as executor:
    # Start the load operations and mark each future with its URL
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        try:
            data = future.result()
        except Exception as exc:
            print('%r generated an exception: %s' % (url, exc))
        else:
            print('%r page is %d bytes' % (url, len(data)))

https://docs.python.org/3/l Library /conx hiện tại .futures.html

    
0
2019-05-08 16: 20: 47Z

Tôi đã kết thúc việc giải quyết điều này bằng cách thay đổi cách tôi thêm vào mảng dữ liệu lớn mà tôi đang thu thập. Thay vì thêm một hàng dữ liệu trong mỗi lần lặp, tôi đã tạo một mảng tạm thời chứa 1000 hàng dữ liệu, sau đó tôi sẽ thêm mảng tạm thời này vào một dữ liệu hoàn chỉnh. Điều này khiến thời gian chạy xuống còn khoảng một phút so với 43 phút trước đó.

rel_info = np.array([("Title", "Author_Name", "Jornal_Published_In", "Date")])

for req_num in range(0, loops):
offset = 1000 * req_num
# keep track of progress
print("Progress:" + str(round((offset/total_res)*100, 2)) + "%")
# get data with request to MAK. 1000 is the max count
url = "https://api.labs.cognitive.microsoft.com/academic/v1.0/evaluate?expr=And(Composite(AA.AfN=='brigham young university'),Y>=1908)&model=latest&count=1000&offset="+str(offset)+"&attributes=Ti,D,AA.DAfN,AA.DAuN,J.JN"
response = req.get(url + '&subscription-key={key}')

data = response.json()

for i in range(0, len(data["entities"])):
    new_data = data["entities"][i]
    # get new data
    new_title = new_data["Ti"]                 # get title

    if 'J' not in new_data:                    # get journal account for if keys are not in dictionaries
        new_journ = ""
    else:
        new_journ = new_data["J"]["JN"] or ""

    new_date = new_data["D"]                   # get date

    new_auth = ""                              # get authors only affiliated with BYU account for if keys are not in dictionary
    for j in range(0, len(new_data["AA"])):
        if 'DAfN' not in new_data["AA"][j]:
            new_auth = new_auth + ""
        else:
            if new_data["AA"][j]["DAfN"] == "Brigham Young University" and new_auth == "":     # posibly combine conditionals to make less complex
                new_auth = new_data["AA"][j]["DAuN"]
            elif new_data["AA"][j]["DAfN"] == "Brigham Young University" and new_auth != "":
                new_auth = new_auth +", "+ new_data["AA"][j]["DAuN"]

    # here are the changes
    # keep adding to a temporary array for 1000 entities
    new_info = np.array([(new_title, new_auth, new_journ, new_date)])
    if (i == 0): work_stack = new_info
    else: work_stack = np.vstack((work_stack, new_info))
# add temporary array to whole array (this is to speed up the program)
rel_info = np.vstack((rel_info, work_stack))
    
0
2019-05-08 17: 43: 15Z
nguồn đặt đây