Một phần đáng kể dữ liệu được tạo ra mỗi ngày vốn mang tính không gian. Từ dữ liệu Quan sát Trái Đất và dữ liệu GPS đến dữ liệu có trong nhiều loại bản đồ, dữ liệu không gian –còn được gọi là dữ liệu địa không gian hoặc thông tin địa lý– là loại dữ liệu mà mỗi bản ghi đều gắn với một vị trí cụ thể.
Mỗi điểm dữ liệu không gian đều có thể được định vị trên bản đồ. Điều này có thể thực hiện bằng một hệ quy chiếu toạ độ nhất định, ví dụ như toạ độ địa lý, dựa trên cặp vĩ độ - kinh độ thường dùng để chỉ vị trí trên địa cầu. Nhờ đó, chúng ta có thể xem xét các mối quan hệ không gian giữa các dữ liệu.
Tuy vậy, sức mạnh thực sự của dữ liệu địa không gian nằm ở việc kết hợp cả bản thân dữ liệu và vị trí của chúng, từ đó mở ra nhiều cơ hội cho các phân tích tinh vi. Cái gọi là khoa học dữ liệu địa không gian là một phân ngành của khoa học dữ liệu, tập trung vào trích xuất thông tin từ dữ liệu địa không gian bằng cách tận dụng sức mạnh của các thuật toán và kỹ thuật phân tích không gian, như học máy và học sâu. Nói cách khác, khoa học dữ liệu địa không gian giúp chúng ta hiểu nơi sự việc diễn ra và tại sao chúng lại diễn ra ở đó.
Có nhiều công cụ phù hợp cho khoa học dữ liệu địa không gian. Hướng dẫn này sẽ tập trung vào GeoPandas, một gói nguồn mở để làm việc với dữ liệu địa không gian trong Python.
GeoPandas mở rộng các kiểu dữ liệu do pandas sử dụng –công cụ tiêu chuẩn để thao tác dataframe trong Python– để cho phép thực hiện các phép toán không gian trên các kiểu hình học. Vì GeoPandas được xây dựng trên pandas –cũng như các gói Python phổ biến khác cho khoa học dữ liệu như matplotlib–, nên các chuyên gia dữ liệu dùng Python có thể nhanh chóng nắm bắt cú pháp GeoPandas.
Cài đặt GeoPandas cho Python
Để sử dụng GeoPandas trong Python, trước hết bạn cần cài đặt nó như các thư viện Python khác.
Lưu ý rằng GeoPandas phụ thuộc vào một tập các thư viện địa không gian nguồn mở để phát huy đầy đủ khả năng không gian của mình, bao gồm shapely, fiona, pyproj và rtree. Bạn cần đảm bảo cài đặt tất cả các phụ thuộc này, nếu không GeoPandas có thể không hoạt động như mong đợi.
Để tránh phức tạp, GeoPandas khuyến nghị cài đặt thư viện bằng trình quản lý gói conda. Điều này có nghĩa bạn sẽ cần cài đặt Anaconda trước. Để biết cách cài đặt và sử dụng Anaconda, hãy xem hướng dẫn của chúng tôi.
Ưu điểm của conda là cung cấp các gói nhị phân dựng sẵn cho toàn bộ các phụ thuộc bắt buộc và tuỳ chọn của GeoPandas trên mọi hệ điều hành (Windows, Mac, Linux). Để cài đặt GeoPandas trên dòng lệnh:
>>conda install geopandas
Ngoài ra, bạn có thể cài đặt Anaconda bằng pip, trình cài đặt gói tiêu chuẩn trong Python. Như đã đề cập, bạn cũng sẽ cần cài đặt các phụ thuộc bắt buộc. Nếu bạn chưa quen với pip, chúng tôi khuyến nghị đọc Hướng dẫn Pip Python về Quản lý Gói. Lệnh bạn cần chạy để cài đặt GeoPandas với pip là:
>>pip install geopandas
Trong mọi trường hợp, nếu gặp sự cố khi cài đặt GeoPandas, bạn nên kiểm tra tài liệu để biết thêm thông tin.
Sau khi cài đặt gói, bạn đã sẵn sàng sử dụng GeoPandas. Chỉ cần import nó vào môi trường Python của bạn. Lưu ý rằng việc import GeoPandas với bí danh gpd là rất phổ biến.
import geopandas as gpd
Các thao tác cơ bản với GeoPandas
Trong phần này, chúng ta sẽ đề cập các thao tác cơ bản nhất bạn có thể làm với GeoPandas. Qua đó, chúng tôi sẽ giới thiệu một số khái niệm then chốt trong phân tích không gian địa lý, bao gồm các loại dữ liệu không gian, định dạng dữ liệu không gian và hệ quy chiếu toạ độ (CRS).
Đọc và ghi dữ liệu không gian
Cũng như pandas cần dữ liệu đầu vào để chuyển thành pandas dataframe, GeoPandas đọc dữ liệu (không gian) đầu vào và chuyển nó thành đối tượng gọi là GeoDataFrame.
Trước khi đi vào các kiểu tệp không gian mà GeoPandas có thể đọc, điều quan trọng là phân biệt các loại dữ liệu không gian khác nhau. Loại dữ liệu chúng ta xử lý sẽ cho biết nên dùng công cụ nào để phân tích rồi trực quan hoá dữ liệu.
Về cơ bản, có hai loại dữ liệu không gian chính:
- Dữ liệu vector. Mô tả các đối tượng ở vị trí địa lý trên Trái Đất thông qua các hình học rời rạc, cụ thể là:
- Điểm. Các vị trí riêng lẻ, như một toà nhà hoặc một chiếc xe, với toạ độ X và Y.
- Đường. Một chuỗi điểm nối nhau mô tả các đối tượng như đường xá hoặc suối.
- Vùng (Polygon). Hình thành bởi một đường khép kín bao quanh một diện tích, chẳng hạn ranh giới một quốc gia. Ngoài ra, khi một đối tượng gồm nhiều hình học, ta gọi đó là MultiPolygon.
- Dữ liệu raster. Mã hoá thế giới như một bề mặt liên tục được biểu diễn bằng một lưới, giống như các pixel của ảnh. Mỗi ô của lưới có thể là một giá trị liên tục (như độ cao) hoặc một phân loại theo danh mục (như phân loại lớp phủ đất). Ví dụ kinh điển gồm dữ liệu độ cao hoặc ảnh vệ tinh.

Nguồn: Đại học Humboldt State
Cả dữ liệu vector và raster thường đi kèm với dữ liệu phi không gian, còn gọi là thuộc tính. Dữ liệu không gian có thể có bất kỳ số lượng thuộc tính bổ sung nào đi kèm thông tin về vị trí. Chẳng hạn, vị trí của một trường học có thể gắn với tên trường, số lượng học sinh hoặc địa chỉ.
GeoPandas được thiết kế để làm việc với dữ liệu vector, dù nó có thể dễ dàng kết hợp với các gói Python khác để xử lý dữ liệu raster, như rasterio. Để đọc dữ liệu không gian, GeoPandas cung cấp hàm geopandas.read_file(). Hàm mạnh mẽ này có thể tự động đọc hầu hết các định dạng dữ liệu không gian dựa trên vector thường gặp.
Một số định dạng dữ liệu vector phổ biến nhất gồm:
- Shapefile. Là tiêu chuẩn trong ngành, shapefile là định dạng dữ liệu vector phổ biến nhất. Nó gồm ba tệp thường được cung cấp trong một tệp zip:
- Tệp .shp chứa hình học.
- Tệp .dbf lưu các thuộc tính cho mỗi hình học,
- Tệp .shx hay tệp chỉ mục hình học giúp liên kết thuộc tính với hình dạng.
- GeoJSON. Đây là định dạng mới hơn cho dữ liệu địa không gian, phát hành năm 2016. Không như shapefile, GeoJSON là một tệp đơn, giúp làm việc thuận tiện hơn.
Trong các ví dụ sau, chúng ta sẽ dùng hàm geopandas.read_file() để đọc một tệp GeoJSON lưu trên GitHub chứa dữ liệu địa không gian về các quận khác nhau của thành phố Barcelona.
url = 'https://raw.githubusercontent.com/jcanalesluna/bcn-geodata/master/districtes/districtes.geojson'
districts = gpd.read_file(url)
districts

Chúng ta sẽ quay lại bộ dữ liệu này sau, nhưng trước hết, bạn cần biết cách ghi một GeoDataFrame ra tệp. Cách làm khá đơn giản. Bạn chỉ cần dùng GeoDataFrame.to_file() để tạo một tệp chứa dữ liệu không gian. Mặc định, định dạng của tệp mới sẽ là shapefile, nhưng bạn có thể thay đổi bằng tham số “driver”.
Ví dụ, bạn lưu GeoDataFrame các quận thành một tệp geoJSON:
districts.to_file("districts.geojson", driver="GeoJSON")
Khám phá GeoDataFrame
Bạn có thể nhận thấy GeoDataFrame ở phần trước giống với một pandas dataframe truyền thống. Điều này hợp lý vì GeoDataFrame là một lớp con của pandas.DataFrame. Nghĩa là nó kế thừa nhiều phương thức và thuộc tính của pandas dataframe. Điểm mới ở GeoDataFrame là nó có thể lưu các cột hình học (còn gọi là GeoSeries) và thực hiện các phép toán không gian.
Cột hình học có thể chứa bất kỳ loại dữ liệu vector nào, như điểm, đường và polygon. Hơn nữa, cần lưu ý rằng mặc dù một GeoDataFrame có thể có nhiều GeoSeries, chỉ một cột được coi là hình học đang hoạt động, tức mọi phép toán không gian sẽ dựa trên cột đó.

Nguồn: GeoPandas
Một đặc điểm quan trọng khác của GeoDataFrame là mỗi GeoSeries đi kèm thông tin CRS. Thông tin CRS cho GeoPandas biết các toạ độ nằm ở đâu trên Trái Đất. Đây là thông tin then chốt cho phân tích không gian. Ví dụ, nếu bạn cần kết hợp hai bộ dữ liệu không gian, bạn phải đảm bảo chúng được biểu diễn trong cùng một CRS. Nếu không, bạn sẽ không nhận được kết quả như mong đợi.
Có hai nhóm CRS chính:
- Toạ độ địa lý. Xác định vị trí toàn cầu bằng đơn vị độ vĩ độ và kinh độ so với xích đạo và kinh tuyến gốc. Với hệ này, ta có thể dễ dàng chỉ định bất kỳ vị trí nào trên Trái Đất. Nó được dùng rộng rãi, ví dụ trong GPS. CRS phổ biến nhất là EPSG:4326, còn gọi là WGS84.
- Toạ độ phẳng (projected). Dù Trái Đất là hình cầu, chúng ta thường biểu diễn nó trên bản đồ hai chiều. Toạ độ phẳng biểu diễn vị trí theo hai trục X và Y, cho phép làm việc với đơn vị độ dài như mét thay vì độ, giúp phân tích thuận tiện và hiệu quả hơn. Tuy nhiên, việc chuyển từ Trái Đất ba chiều sang bản đồ hai chiều tất yếu gây ra biến dạng. Vì vậy, có nhiều cách tiếp cận khác nhau để tạo hệ toạ độ phẳng. Chẳng hạn, nhiều quốc gia đã áp dụng một chuẩn CRS phẳng cho địa lý riêng của họ.
Còn rất nhiều điều về CRS, nhưng nằm ngoài phạm vi của hướng dẫn này. Một nguồn tài liệu tuyệt vời để tìm hiểu thêm thông tin và ví dụ thực hành là khóa Working with Geospatial Data in Python của chúng tôi.
Trong GeoPandas, thông tin CRS được lưu trong thuộc tính crs:
districts.crs

GeoDataFrame về các quận đang gắn với toạ độ địa lý (EPSG: 4326), nhưng chúng ta muốn chuyển nó sang toạ độ phẳng để có thể tính toán theo đơn vị mét. Hãy chuyển sang EPSG:2062, CRS phẳng tiêu chuẩn cho Tây Ban Nha. Ta có thể làm điều này với phương thức Geopandas.to_crs().
districts.to_crs(epsg=2062, inplace=True)
districts.crs

Giờ đây, sau khi đã đặt đúng CRS phẳng, chúng ta sẵn sàng khám phá các thuộc tính của GeoDataFrame.
Khám phá thuộc tính của bộ dữ liệu không gian
GeoPandas kế thừa một số phương thức và thuộc tính hữu ích từ gói shapely. Chúng ta sẽ đề cập bốn trong số đó.
Diện tích
Thuộc tính area trả về diện tích đã tính của một hình học. Ta có thể lưu diện tích thu được (chuyển sang km2) vào một cột mới:
districts['area'] = districts.area / 1000000
districts
Trọng tâm (Centroid)
Thuộc tính centroid trả về điểm trung tâm của một hình học. Ta có thể thêm nó vào bộ dữ liệu, tạo ra một cột hình học mới.
districts['centroid']=districts.centroid
districts
Biên (Boundary)
Thuộc tính boundary trả về đường ranh giới của một polygon.
districts['boundary']=districts.boundary
Khoảng cách
Phương thức distance cho biết khoảng cách nhỏ nhất từ một hình học đến một vị trí. Giả sử chúng ta muốn tính khoảng cách từ nhà thờ Sagrada Familia nổi tiếng, nằm ở quận Eixample, đến trọng tâm của mọi quận ở Barcelona, rồi thêm các khoảng cách này (theo kilômét) vào một cột mới.

Nhà thờ Sagrada Familia. Nguồn: Wikipedia
Trước tiên, chúng ta cần tạo một điểm bằng hàm Point() của shapely với toạ độ mong muốn (bạn có thể dễ dàng tìm trên Google Maps), chuyển nó thành GeoSeries với CRS phù hợp, rồi dùng phương thức GeoPandas.distance():
from shapely.geometry import Point
sagrada_fam = Point(2.1743680500855005, 41.403656946781304)
sagrada_fam = gpd.GeoSeries(sagrada_fam, crs=4326)
sagrada_fam= sagrada_fam.to_crs(epsg=2062)
districts['sagrada_fam_dist'] = [float(sagrada_fam.distance(centroid)) / 1000 for centroid in districts.centroid]
Bộ dữ liệu thu được sau các phép toán không gian trước đó trông như sau:

Vẽ biểu đồ với GeoPandas
Các phép toán không gian chúng ta đã thực hiện cung cấp thông tin hữu ích cho nghiên cứu. Tuy nhiên, trực quan hoá các hình học trong không gian là một cách tuyệt vời để nâng cao phân tích. May mắn thay, tạo biểu đồ GeoPandas rất dễ. Bạn chỉ cần gọi hàm GeoDataFrame.plot(), được xây dựng dựa trên gói matplotlib của Python.
Hãy bắt đầu với một trực quan cơ bản về các quận của Barcelona.
ax= districts.plot(figsize=(10,6))

Chúng ta có thể làm cho biểu đồ GeoPandas thông tin hơn bằng cách tô màu từng quận. Đặt legend là 'True' sẽ tạo chú giải giúp diễn giải màu sắc.
ax= districts.plot(column=district_name', figsize=(10,6), edgecolor='black', legend=True)

Cuối cùng, chúng ta có thể thêm các trọng tâm của quận và Sagrada Familia vào bản đồ, cũng như một tiêu đề. Đồng thời, để biểu đồ hấp dẫn hơn, ta có thể dùng gói contextily để thêm lớp nền tile map của thành phố Barcelona thực tế.
import contextily
ax= districts.plot(column='district_name', figsize=(12,6), alpha=0.5, legend=True)
districts["centroid"].plot(ax=ax, color="green")
sagrada_fam.plot(ax=ax,color='black', marker='+')
contextily.add_basemap(ax, crs=districts.crs.to_string())
plt.title('A Beautiful Map of Barcelona')
plt.axis('off')
plt.show()

Tuyệt vời, phải không? Bạn còn có thể làm nhiều hơn nữa để tạo các trực quan không gian đẹp mắt. Khóa học Visualizing Spatial Data With Python của chúng tôi là nguồn học liệu tuyệt vời để nâng tầm kỹ năng trực quan hoá của bạn.
Các quan hệ không gian với GeoPandas
Một trong những khía cạnh then chốt của dữ liệu địa không gian là cách chúng liên hệ với nhau trong không gian. GeoPandas tận dụng sức mạnh của pandas và shapely để thực hiện đủ loại quan hệ không gian giữa các bộ dữ liệu không gian. Trong phần này, chúng ta sẽ đề cập một số thao tác thường gặp.
Join theo thuộc tính
Có hai cách để kết hợp các bộ dữ liệu trong pandas: join theo thuộc tính và join theo không gian.
Join theo thuộc tính cho phép chúng ta nối hai GeoDataFrame dựa trên các biến không phải hình học, giống như join thông thường trong pandas. Thực tế, cách thực hiện join theo thuộc tính là dùng phương thức pandas.merge() tiêu chuẩn. Nếu bạn muốn tìm hiểu thêm về join trong pandas, hãy xem hướng dẫn Joining DataFrames in pandas của chúng tôi.
Ví dụ, sẽ rất hữu ích nếu làm giàu GeoDataFrame của chúng ta bằng dữ liệu dân số của Barcelona năm 2022.
pop =pd.read_csv('poblacion_barna_2022.csv', usecols=['Nom_Districte','Nombre'])
pop = pd.DataFrame(pop.groupby('Nom_Districte')['Nombre'].sum()).reset_index()
pop.columns=['district_name','population_22']
districts = districts.merge(pop)
districtsv
Join theo không gian
Ngược lại, join theo không gian cho phép gộp hai GeoDataFrame dựa trên quan hệ không gian của chúng.
Ví dụ, hãy xác định các quận mà làn đường xe đạp ở Barcelona đi qua.
url = 'https://opendata-ajuntament.barcelona.cat/resources/bcn/CarrilsBici/CARRIL_BICI.geojson'
bike_lane = gpd.read_file(url)
bike_lane = bike_lane.loc[:,['ID','geometry']]
bike_lane.to_crs(epsg=2062, inplace=True)


Trong GeoPandas, thao tác join theo không gian có sẵn dưới dạng hàm sjoin(). Đối số đầu tiên là GeoDataFrame mà chúng ta muốn thêm thông tin, và đối số thứ hai là GeoDataFrame chứa thông tin cần thêm. Sau đó, chúng ta phải chỉ định kiểu join. Cuối cùng, tham số “predicate” cho GeoPandas biết quan hệ không gian nào sẽ dùng để ghép hai bộ dữ liệu. Một số quan hệ phổ biến gồm “intersects”, “contains” và “within”.
Trong ví dụ của chúng ta, ta sẽ dùng predicate “intersects”. Hai đối tượng hình học giao nhau nếu chúng có bất kỳ điểm biên hoặc điểm bên trong chung nào.
lanes_districts = gpd.sjoin(districts, bike_lane, how='inner', predicate='intersects')
lanes_districts

Lưu ý rằng GeoDataFrame kết quả có nhiều hàng hơn GeoDataFrame bike_lane. Đó là vì một làn xe đạp có thể nằm trên nhiều quận.
Cuối cùng, chúng ta có thể nhóm bộ dữ liệu để lấy số lượng làn xe đạp theo quận:
lanes_districts.groupby('district_name').size()
Phép chồng lớp (Overlay) trong GeoPandas
Cuối cùng, các phép chồng lớp cho phép bạn so sánh hai GeoDataFrame chứa hình học polygon hoặc multipolygon và tạo một GeoDataFrame mới với các hình học mới đại diện cho sự kết hợp không gian và các thuộc tính đã gộp. Hình dưới minh hoạ các khả năng khác nhau:

Nguồn: GeoPandas
Hãy hình dung Hội đồng Thành phố Barcelona muốn xây dựng các công viên địa phương mới nhằm giải quyết ô nhiễm và thúc đẩy sức khoẻ cộng đồng. Ý tưởng sơ bộ là tạo các công viên tròn lớn trong phạm vi 500 mét tính từ trung tâm của mỗi quận. Chúng ta có thể mô phỏng điều này bằng cách tạo một buffer dựa trên trọng tâm của mỗi quận.
parks = gpd.GeoDataFrame(districts.centroid.buffer(500), geometry=0)
parks.plot()

Bây giờ, chúng ta sẵn sàng thực hiện một số phép chồng lớp. Ví dụ, nếu muốn chỉ xem các khu vực trong quận nơi các công viên sẽ nằm, ta có thể dùng phương thức GeoPandas.overlay():
parks_intersection = districts.overlay(parks, how='intersection')
ax = parks_intersection.plot(alpha=0.5, edgecolor='black', column='district_name')

Hoặc, nếu muốn xem các quận sau khi loại trừ diện tích chiếm bởi các công viên dự kiến, ta có thể đổi tham số “how” để thực hiện phép chồng lớp khác.
parks_difference = districts.overlay(parks, how='difference')
ax = parks_difference.plot(alpha=0.5, edgecolor='black', column='district_name')

Kết luận
Chúng tôi hy vọng bạn thấy thích hướng dẫn GeoPandas này. Phân tích không gian là một trong những lĩnh vực thú vị nhất trong khoa học dữ liệu, mang lại vô vàn cơ hội để làm giàu phân tích của bạn bằng thông tin dựa trên vị trí. Có nhiều công cụ cho phân tích không gian, nhưng nếu bạn đã quen với Python, GeoPandas là điểm khởi đầu tuyệt vời.
Muốn tiếp tục học về địa không gian? Chúng tôi đã chuẩn bị sẵn cho bạn! Hãy xem các tài liệu sau và trở thành chuyên gia địa không gian:
Câu hỏi thường gặp về GeoPandas
Phân tích dữ liệu địa không gian là gì?
Khoa học dữ liệu địa không gian là một phân ngành của khoa học dữ liệu, tập trung vào trích xuất thông tin từ dữ liệu địa không gian bằng cách tận dụng sức mạnh của các thuật toán và kỹ thuật phân tích không gian.
GeoPandas là gì?
GeoPandas là một dự án nguồn mở giúp việc làm với dữ liệu địa không gian trong Python trở nên dễ dàng hơn.
Sự khác biệt giữa pandas và GeoPandas là gì?
GeoPandas mở rộng các kiểu dữ liệu do pandas sử dụng để cho phép các phép toán không gian trên các kiểu hình học. GeoPandas sử dụng pandas DataFrame để tạo đối tượng gọi là GeoDataFrame.
Lập trình viên R có thể học phân tích không gian như thế nào?
Ngoài các khóa học Python, DataCamp còn có rất nhiều khóa học và lộ trình học về không gian dành cho lập trình viên R.



