Tôi có một số tập tin văn bản, nói 50, mà tôi cần phải đọc vào một dataframe lớn. Hiện tại, tôi đang sử dụng các bước sau.Làm cách nào để tăng tốc độ đọc nhiều tệp và đưa dữ liệu vào một khung dữ liệu?
- Đọc mọi tệp và kiểm tra xem nhãn là gì. Thông tin tôi cần thường được chứa trong một vài dòng đầu tiên. Các nhãn giống nhau chỉ lặp lại cho phần còn lại của tệp, với các loại dữ liệu khác nhau được liệt kê dựa trên chúng mỗi lần.
- Tạo một khung dữ liệu với các nhãn đó.
- Đọc lại tệp và điền vào khung dữ liệu với các giá trị.
- Kết hợp khung dữ liệu đó với một khung dữ liệu chính.
Điều này hoạt động khá tốt đối với các tệp có kích thước 100 KB - một vài phút, nhưng ở mức 50 MB, chỉ mất vài giờ và không thực tế.
Tôi làm cách nào để tối ưu hóa mã của mình? Cụ thể -
- Làm cách nào để xác định những chức năng nào đang dùng nhiều thời gian nhất mà tôi cần tối ưu hóa? Có phải đọc tệp không? Nó có phải là văn bản cho khung dữ liệu không? Chương trình của tôi dành thời gian ở đâu?
- Tôi có nên xem xét đa luồng hoặc đa xử lý không?
- Tôi có thể cải thiện thuật toán không?
- Có lẽ đọc toàn bộ tập tin trong một đi vào một danh sách, chứ không phải là từng dòng,
- dữ liệu Parse trong khối/toàn bộ tập tin, chứ không phải là từng dòng,
- dữ liệu Gán cho dataframe trong khối/một đi, thay vì hàng theo hàng.
- Có bất kỳ điều gì khác mà tôi có thể thực hiện để làm cho mã của mình chạy nhanh hơn không?
Đây là mã ví dụ. Mã của riêng tôi phức tạp hơn một chút, vì các tệp văn bản phức tạp hơn nên tôi phải sử dụng khoảng 10 cụm từ thông dụng và nhiều vòng lặp để đọc dữ liệu và phân bổ nó đến đúng vị trí trong mảng bên phải. Để giữ cho MWE đơn giản, tôi đã không sử dụng các nhãn lặp lại trong các tệp đầu vào cho MWE, vì vậy nó muốn tôi đọc tệp hai lần mà không có lý do gì. Tôi hy vọng điều đó đúng!
import re
import pandas as pd
df = pd.DataFrame()
paths = ["../gitignore/test1.txt", "../gitignore/test2.txt"]
reg_ex = re.compile('^(.+) (.+)\n')
# read all files to determine what indices are available
for path in paths:
file_obj = open(path, 'r')
print file_obj.readlines()
['a 1\n', 'b 2\n', 'end']
['c 3\n', 'd 4\n', 'end']
indices = []
for path in paths:
index = []
with open(path, 'r') as file_obj:
line = True
while line:
try:
line = file_obj.readline()
match = reg_ex.match(line)
index += match.group(1)
except AttributeError:
pass
indices.append(index)
# read files again and put data into a master dataframe
for path, index in zip(paths, indices):
subset_df = pd.DataFrame(index=index, columns=["Number"])
with open(path, 'r') as file_obj:
line = True
while line:
try:
line = file_obj.readline()
match = reg_ex.match(line)
subset_df.loc[[match.group(1)]] = match.group(2)
except AttributeError:
pass
df = pd.concat([df, subset_df]).sort_index()
print df
Number
a 1
b 2
c 3
d 4
tập tin đầu vào của tôi:
test1.txt
a 1
b 2
end
test2.txt
c 3
d 4
end
Có thể có đĩa nhanh hơn :) –
Trong thời gian chờ đợi, hãy tìm kiếm một trình thu thập thông tin bằng Python tốt. Đó là lớp chung của công cụ sẽ cho bạn biết phần nào của chương trình là nút cổ chai. –
Bạn có thể không đọc toàn bộ 50 tệp trong dataframe và sau đó chạy các thao tác dựa trên regex không? Điều đó sẽ nhanh chóng như các hoạt động lọc trên gấu trúc rất nhanh .... – vks