Python xử lý các tệp lớn như thế nào?

Những gì chúng ta đã thấy cho đến nay hầu hết hợp lệ khi xử lý các tệp dữ liệu “nhỏ”. Nhỏ nghĩa là bất kỳ kích thước nào mà máy tính xách tay của bạn có thể xử lý ngày hôm nay trong một khoảng thời gian “hợp lý”… Trong bài học này, mục tiêu của chúng tôi là cho bạn thấy cách giới thiệu xử lý song song có thể tăng tốc công việc xử lý dữ liệu của bạn. Khi xử lý các tệp rất lớn, máy tính xách tay hoặc máy chủ cục bộ của bạn không đủ và bạn cần chuyển công việc của mình sang cơ sở hạ tầng máy tính dữ liệu quốc gia hoặc châu Âu. Bài học sơ bộ này nhằm mục đích dạy cho bạn những điểm chính đối với việc sử dụng các cơ sở lớn hơn. Tuy nhiên, chúng tôi vẫn sử dụng tài nguyên điện toán cục bộ i. e. máy tính xách tay của riêng bạn nhưng chúng tôi đặc biệt khuyến khích bạn kiểm tra và dùng thử trên các cơ sở máy tính lớn hơn

Nhận xét

Không có nghĩa là bài học này có ý định đánh giá các khả năng hiện có với những điểm mạnh và hạn chế của chúng

Đọc các tệp netCDF-4 hoặc HDF-5 có kích thước trung bình đến lớn

Trước tiên, chúng tôi cần tạo một bộ dữ liệu netCDF “lớn hơn”;

cp EI_VO_850hPa_Summer2001.nc large.nc

Và chúng tôi thêm dữ liệu bổ sung vào thứ nguyên không giới hạn của nó [thời gian]

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]

Như bạn có thể thấy việc ghi tập dữ liệu này khá chậm… nhưng sau này chúng ta sẽ xem cách chúng ta có thể cải thiện hiệu suất khi ghi tệp netCDF như thế nào. Trước tiên, chúng tôi xem cách chúng tôi có thể đọc tệp này trên máy tính xách tay có bộ nhớ

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
8

Đọc một lát của tập dữ liệu

Khi tệp netCDF của bạn trở nên lớn, bạn khó có thể đưa toàn bộ tệp vào bộ nhớ máy tính xách tay của mình. Bạn có thể cắt tập dữ liệu của mình và tải nó để nó có thể vừa với bộ nhớ máy tính xách tay của bạn. Bạn có thể cắt các biến netCDF bằng cú pháp tương tự như mảng có nhiều mảng

%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]

Chuỗi thời gian

Sử dụng ví dụ trước nhưng trích xuất tất cả dữ liệu cho một vị trí địa lý duy nhất [lấy bất kỳ vị trí nào]

Dung dịch

from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[:,0,30,30]

Thời gian đã trôi qua để trích xuất lát cắt của bạn phụ thuộc rất nhiều vào cách dữ liệu của bạn được lưu trữ [cách tổ chức các thứ nguyên]

%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# print some metadata
print[d]
d.close[]


root group [NETCDF3_CLASSIC data model, file format NETCDF3]:
    CDI: Climate Data Interface version 1.7.0 [//mpimet.mpg.de/cdi]
    Conventions: CF-1.4
    history: Thu Feb 04 14:28:54 2016: cdo -t ecmwf -f nc copy EI_VO.grb EI_VO.nc
    institution: European Centre for Medium-Range Weather Forecasts
    CDO: Climate Data Operators version 1.7.0 [//mpimet.mpg.de/cdo]
    dimensions[sizes]: lon[512], lat[256], lev[1], time[200368]
    variables[dimensions]: float64 lon[lon], float64 lat[lat], float64 lev[lev], float64 time[time], float32 VO[time,lev,lat,lon]
    groups:

Trong trường hợp của chúng tôi, thứ nguyên

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
9 thay đổi chậm nhất và thứ nguyên
%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
0 là nhanh nhất

**Nguồn. http. //www. thống nhất dữ liệu. ucar. edu/blogs/developer/entry/chunking_data_why_it_matters **

Lý do là khi lưu trữ tập dữ liệu của chúng tôi, chúng tôi đã sử dụng bố cục lưu trữ netCDF mặc định. e. bố cục lưu trữ liền kề [thứ tự chỉ mục] thông thường

Vì vậy, tùy thuộc vào cách bạn muốn truy cập [để xử lý hậu kỳ hoặc trực quan hóa] dữ liệu của mình, đây có thể là cách tiếp cận tốt nhất hoặc tệ nhất

Một sự thỏa hiệp tốt là sử dụng phân đoạn, lưu trữ dữ liệu đa chiều trong các khối hình chữ nhật đa chiều để tăng tốc độ truy cập chậm với chi phí làm chậm truy cập nhanh. Các chương trình truy cập dữ liệu chunked có thể không biết chunking được sử dụng như thế nào. Chunking được hỗ trợ trong lớp HDF5 của tệp netCDF-4 và là một trong những tính năng, cùng với tính năng nén theo từng đoạn, dẫn đến đề xuất sử dụng HDF5 làm lớp lưu trữ cho netCDF-4 vào năm 2002

**Nguồn. http. //www. thống nhất dữ liệu. ucar. edu/blogs/developer/entry/chunking_data_why_it_matters **

Nếu bạn muốn tìm hiểu thêm về chủ đề này, hãy đọc blog này tại đây

Mẹo dữ liệu

Chọn bố cục lưu trữ phù hợp với mẫu truy cập [đọc] của bạn khi xử lý hậu kỳ hoặc trực quan hóa dữ liệu chứ không phải khi bạn viết. Viết lại dữ liệu theo một bố cục khác có thể mang lại hiệu quả…

netCDF/HDF Nén dữ liệu

Ngoài việc phân đoạn dữ liệu, bạn có thể nén các biến netCDF/HDF một cách nhanh chóng. HDF5 thường có thể dễ dàng đạt đến mức nén rất tốt khi sử dụng thư viện

%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
1 [để có được chức năng này, netCDF-4 và HDF5 cần được biên dịch với thư viện
%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
1]

Hãy lấy tệp

%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
3 trước đây của chúng tôi và viết lại nó bằng cách nén

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
2

Nén dữ liệu

Sử dụng nén dữ liệu netCDF-4 / HDF-5 khi ghi tập dữ liệu của bạn để tiết kiệm dung lượng ổ đĩa. NetCDF4 và HDF5 cung cấp các phương pháp dễ dàng để nén dữ liệu. Khi bạn tạo các biến, bạn có thể bật tính năng nén dữ liệu bằng cách đặt đối số từ khóa zlib=True nhưng bạn cũng có thể chọn tỷ lệ nén và độ chính xác của dữ liệu của mình

  • Đối số từ khóa
    %matplotlib inline
    from netCDF4 import Dataset    
    d = Dataset['large.nc', 'r']
    # Do not load dataset yet
    data=d.variables['VO']
    # pick-up a time and read VO
    slice_t=data[1000,:,:,:]
    d.close[]
    
    4 chuyển đổi tỷ lệ nén và tốc độ. Các tùy chọn nằm trong khoảng từ 1 đến 9 [1 là nhanh nhất với độ nén ít nhất và 9 là chậm nhất với độ nén nhiều nhất. Mặc định là 4]
  • Độ chính xác của dữ liệu của bạn có thể được chỉ định bằng đối số từ khóa
    %matplotlib inline
    from netCDF4 import Dataset    
    d = Dataset['large.nc', 'r']
    # Do not load dataset yet
    data=d.variables['VO']
    # pick-up a time and read VO
    slice_t=data[1000,:,:,:]
    d.close[]
    
    5. Số float thường được lưu trữ với độ chính xác cao hơn nhiều so với dữ liệu mà nó đại diện, đặc biệt nếu bạn xử lý các giá trị được quan sát. Các chữ số ở cuối chiếm nhiều dung lượng và có thể không liên quan. Bằng cách chỉ định chữ số ít quan trọng nhất, bạn có thể nâng cao hơn nữa khả năng nén dữ liệu. Điều này chỉ mang lại cho netCDF nhiều tự do hơn khi nó đóng gói dữ liệu vào ổ cứng của bạn. Chẳng hạn, biết rằng nhiệt độ chỉ chính xác đến khoảng 0. 005 độ K, chỉ cần bảo toàn 4 số đầu là hợp lý

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
5

Tạo lại tập dữ liệu bằng dòng trên có thể giảm đáng kể kích thước netCDF của bạn, đặc biệt là trên các tập dữ liệu lớn. Bạn có thể tìm thêm thông tin ở đây. Và đây cho các tệp HDF5;

  • Nén dữ liệu HDF5 được làm sáng tỏ Phần 1
  • Giải mã nén dữ liệu HDF5 Phần 2. Điều chỉnh hiệu suất
Điện toán song song để phân tích dữ liệu không gian-thời gian. bóng tối

dask. một thư viện tính toán song song linh hoạt cho tính toán phân tích

Chúng tôi thường có tập dữ liệu lớn để xử lý; . Việc sử dụng python như chúng ta đã làm cho đến nay không thể thực hiện được nữa

  • các tệp của chúng tôi quá lớn để vừa với bộ nhớ
  • quá trình xử lý dữ liệu của chúng tôi quá dài để chạy trên một bộ xử lý

Chúng tôi đã thấy rằng việc phân đoạn dữ liệu rất hiệu quả nhưng việc viết chương trình mà chúng tôi vừa phân đoạn dữ liệu vừa xử lý có thể rất cồng kềnh. Và để tăng tốc quá trình xử lý của chúng tôi, chúng tôi cần sử dụng nhiều hơn một bộ xử lý, vì vậy chúng tôi cần một khung đủ đơn giản và hiệu quả trên quy mô lớn

Dask là một thư viện python giúp tính toán song song trên khối dữ liệu lớn. Điều này cho phép phân tích dữ liệu không vừa với bộ nhớ máy tính của bạn cũng như tận dụng khả năng đa xử lý của máy

Xem phần giới thiệu Dask rất hay. Điện toán song song bằng Python do Matthew Rocklin thực hiện tại Hội nghị dữ liệu Strata 2017

Hãy xem cách nó hoạt động với một ví dụ

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
6

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
7

Cho đến nay, chúng tôi vừa mở một tệp HDF5 bằng

%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
6 [gói này là API mức rất thấp để đọc các tệp HDF5; nó thường rất hiệu quả] và đọc
%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
7 [Mật độ cột dọc của Ozone]. Đó là trường 2D, vì vậy khi chúng tôi tạo một mảng
%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
8, chúng tôi có thể tách nó ra

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
0

Chúng tôi chưa tính toán bất cứ điều gì vì tất cả các hoạt động với

%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
8 đều bị hoãn lại. Nhưng chúng ta đã có thể thấy tập hợp các thao tác cần thiết để tính giá trị lớn nhất

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
1

Bạn phải nhìn hình từ dưới lên trên. Ở dưới cùng, bạn thấy tất cả các khối của mình [ở đây là 10] và ở trên cùng là kết quả cuối cùng [giá trị tối đa của toàn bộ trường]

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
2

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
3

Ở đây, tập hợp các hoạt động được tuần tự hóa vì chúng tôi không chạy nó trên máy tính đa bộ xử lý nhưng với những thay đổi đáng kể, bạn có thể chạy mã tương tự với các tệp lớn và trên một số lượng lớn bộ xử lý

Và ngay cả trên máy tính xách tay của bạn,

%matplotlib inline
from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[1000,:,:,:]
d.close[]
8 có thể rất hữu ích vì nó cho phép các hoạt động ngoài lõi. Điều này có nghĩa là nếu tệp của bạn không vừa với bộ nhớ của máy tính, bạn vẫn có thể chạy thao tác lớn trên tệp đó;

Hãy lấy một ví dụ khác

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
4

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
5

%matplotlib inline
from netCDF4 import Dataset 
import numpy as np
# Read and Append to an existing netCDF file
d = Dataset['large.nc', 'a']

data=d.variables['VO']
t=d.variables['time']

last_time=t[t.size-1]
VO=data[0,:,:,:]

appendvar = d.variables['VO']
for nt in range[t.size,t.size+50]:
# there are 100 times in the file originally
    VO += 0.1 * np.random.randn[]
    last_time += 6.0
    appendvar[nt] = VO
    t[nt] = last_time
d.close[]
6

Sử dụng dask để tính độ lệch chuẩn

Sử dụng cùng một tệp

from netCDF4 import Dataset    
d = Dataset['large.nc', 'r']
# Do not load dataset yet
data=d.variables['VO']
# pick-up a time and read VO
slice_t=data[:,0,30,30]
1 và truy xuất giá trị trung bình về trường ban đầu bằng cách sử dụng dask. Trực quan hóa biểu đồ của các nhiệm vụ trước khi tính toán nó

Python đọc các tệp lớn như thế nào?

Để đọc các tệp văn bản lớn trong Python, chúng ta có thể sử dụng đối tượng tệp làm trình vòng lặp để lặp qua tệp và thực hiện tác vụ được yêu cầu . Vì trình vòng lặp chỉ lặp lại trên toàn bộ tệp và không yêu cầu bất kỳ cấu trúc dữ liệu bổ sung nào để lưu trữ dữ liệu, nên bộ nhớ tiêu thụ tương đối ít hơn.

Có giới hạn kích thước tệp cho Python không?

Không có giới hạn tối đa về kích thước tệp mà Python có thể mở . Mọi người thường xuyên tải hàng gigabyte dữ liệu vào bộ nhớ. Tùy thuộc vào RAM máy tính của bạn và hệ điều hành/bộ xử lý 64 bit hay 32 bit, mức tối đa thực tế cho bạn có thể là từ 1 GB trở lên trước khi bạn gặp lỗi MemoryError.

Làm cách nào để đọc tệp 10gb bằng Python?

Cách nhanh nhất của Python để đọc tệp văn bản lớn [vài GB] .
# Tập tin. readline-ví dụ-3. py
tệp = mở ["mẫu. txt"]
trong khi 1
dòng = tập tin. đường đọc[100000]
nếu không dòng
nghỉ
cho dòng trong dòng
vượt qua # làm gì đó**văn bản mạnh**

Các tệp được xử lý bằng Python như thế nào?

Xử lý tệp . Hàm open[] nhận hai tham số; . open[] function. The open[] function takes two parameters; filename, and mode.

Chủ Đề