已知出租车轨迹中的纬度、经度、时间数据请利用python分析热点交互网络并进行可视化展示输出代码不使用folium库
为了分析出租车轨迹中的热点交互网络,我们可以先进行以下步骤:
- 根据数据中的经纬度信息,将地图划分成一定数量的网格。
- 统计每个网格内出现的出租车数量。
- 对于每个网格,计算其周围八个网格的出租车数量和距离,并计算其与周围网格的交互强度。
- 将每个网格的交互强度作为节点,将每个网格与周围八个网格的交互强度作为边,构成一个无向加权图。
- 对于图中的每个节点,计算其度数和介数中心性,并标记出度数和介数中心性较高的节点作为热点网格。
- 将热点网格的位置标记在地图上,并将热点网格之间的边以不同的颜色和宽度绘制在地图上,以展示热点交互网络。
以下是实现上述步骤的Python代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
data = pd.read_csv('taxi_trajectory.csv')
# 将经纬度信息转换为网格坐标
min_lon, max_lon = data['lon'].min(), data['lon'].max()
min_lat, max_lat = data['lat'].min(), data['lat'].max()
# 网格数量
grid_size = 50
# 计算每个网格的经纬度范围
lon_step = (max_lon - min_lon) / grid_size
lat_step = (max_lat - min_lat) / grid_size
lon_range = [(min_lon + i * lon_step, min_lon + (i + 1) * lon_step)
for i in range(grid_size)]
lat_range = [(min_lat + i * lat_step, min_lat + (i + 1) * lat_step)
for i in range(grid_size)]
# 统计每个网格内出现的出租车数量
grid_counts = np.zeros((grid_size, grid_size))
for _, row in data.iterrows():
lon, lat = row['lon'], row['lat']
# 找到所在的网格
for i, (lon_min, lon_max) in enumerate(lon_range):
if lon_min <= lon < lon_max:
for j, (lat_min, lat_max) in enumerate(lat_range):
if lat_min <= lat < lat_max:
grid_counts[i, j] += 1
break
break
# 计算每个网格的交互强度
interaction_strength = np.zeros((grid_size, grid_size, 8))
for i in range(grid_size):
for j in range(grid_size):
for k, (delta_i, delta_j) in enumerate([(1, 0), (1, 1), (0, 1),
(-1, 1), (-1, 0),
(-1, -1), (0, -1), (1, -1)]):
# 计算相邻网格的坐标
adjacent_i, adjacent_j = i + delta_i, j + delta_j
if 0 <= adjacent_i < grid_size and 0 <= adjacent_j < grid_size:
# 计算距离和交互强度
distance = np.sqrt(delta_i ** 2 + delta_j ** 2)
interaction_strength[i, j, k] = (grid_counts[adjacent_i, adjacent_j]
/ distance)
# 构建无向加权图
edges = []
edge_weights = []
for i in range(grid_size):
for j in range(grid_size):
if grid_counts[i, j] > 0:
# 添加自环
edges.append((i, j, 0))
edge_weights.append(0)
# 添加相邻边
for k in range(8):
adjacent_i, adjacent_j = i + delta_i, j + delta_j
if 0 <= adjacent_i < grid_size and 0 <= adjacent_j < grid_size:
weight = interaction_strength[i, j, k]
if weight > 0:
edges.append((i, j, 1))
edge_weights.append(weight)
# 计算节点的度数和介数中心性
node_degrees = np.sum(grid_counts > 0, axis=2)
node_betweenness = np.zeros((grid_size, grid_size))
for i in range(grid_size):
for j in range(grid_size):
if grid_counts[i, j] > 0:
# 计算节点的介数中心性
adjacencies = [(i + delta_i, j + delta_j)
for delta_i, delta_j in [(1, 0), (1, 1), (0, 1),
(-1, 1), (-1, 0),
(-1, -1), (0, -1), (1, -1)]
if 0 <= i + delta_i < grid_size and 0 <= j + delta_j < grid_size]
for k, (delta_i, delta_j) in enumerate(adjacencies):
if grid_counts[delta_i, delta_j] > 0:
node_betweenness[i, j] += (node_degrees[delta_i, delta_j]
/ node_degrees[i, j])
# 标记热点网格
threshold_degree = np.percentile(node_degrees, 90)
threshold_betweenness = np.percentile(node_betweenness, 90)
hotspots = [(i, j) for i in range(grid_size)
for j in range(grid_size)
if node_degrees[i, j] >= threshold_degree
or node_betweenness[i, j] >= threshold_betweenness]
# 可视化展示
fig, ax = plt.subplots(figsize=(10, 10))
ax.set_xlim(min_lon, max_lon)
ax.set_ylim(min_lat, max_lat)
# 绘制网格
for i in range(grid_size):
for j in range(grid_size):
if grid_counts[i, j] > 0:
lon_min, lat_min = lon_range[i][0], lat_range[j][0]
ax.add_patch(plt.Rectangle((lon_min, lat_min), lon_step, lat_step,
facecolor='none', edgecolor='gray'))
# 绘制热点网格
for i, j in hotspots:
lon_min, lat_min = lon_range[i][0], lat_range[j][0]
ax.add_patch(plt.Rectangle((lon_min, lat_min), lon_step, lat_step,
facecolor='red', edgecolor='none'))
# 绘制热点网格之间的边
for i, j in hotspots:
for k, (delta_i, delta_j) in enumerate([(1, 0), (1, 1), (0, 1),
(-1, 1), (-1, 0),
(-1, -1), (0, -1), (1, -1)]):
adjacent_i, adjacent_j = i + delta_i, j + delta_j
if 0 <= adjacent_i < grid_size and 0 <= adjacent_j < grid_size:
if (adjacent_i, adjacent_j) in hotspots:
weight = interaction_strength[i, j, k]
if weight > 0:
x = [lon_range[i][0] + lon_step / 2,
lon_range[adjacent_i][0] + lon_step / 2]
y = [lat_range[j][0] + lat_step / 2,
lat_range[adjacent_j][0] + lat_step / 2]
color = 'red' if weight >= np.percentile(edge_weights, 90) else 'gray'
width = weight / np.percentile(edge_weights, 90) * 5
ax.plot(x, y, color=color, linewidth=width)
plt.show()
在以上代码中,我们首先根据数据中的经纬度信息,将地图划分成了一个50x50的网格,并统计了每个网格内出现的出租车数量。然后,我们计算了每个网格的交互强度,并根据交互强度构建了一个无向加权图。接着,我们计算了每个节点的度数和介数中心性,并标记了度数和介数中心性较高的节点作为热点网格。最后,我们将热点网格的位置标记在地图上,并将热点网格之间的边以不同的颜色和宽度绘制在地图上,展示了热点交互网络
原文地址: https://www.cveoy.top/t/topic/e0NV 著作权归作者所有。请勿转载和采集!