在 gdelt-bq.full 数据集,BigQuery 中查找组中事件之间的最大距离
Finding the maximum distance between events in a group in gdelt-bq.full dataset, BigQuery
我需要找到 所有 数据集中每个国家的事件点的最长距离。要获得有关国家/地区的信息,请加入 gdelt-bq:extra.countryinfo
。
所以现在我有了这个 table:
SELECT *
FROM [gdelt-bq:full.events] events JOIN
[gdelt-bq:extra.countryinfo] countries
ON events.Actor1CountryCode = countries.iso3
困难在于总共有大约50k个事件,一个组内最大为15K(对于美国),我需要先计算一个组内的所有距离(一个国家的事件),但是所有事件纬度和经度在一列中。所以我需要创建所有事件对来计算所有事件并找到最长的事件,对于最大的组来说,最长的是 15k 集中的 2 组合的数量,大约是 11kk。
顺便说一句,我在这里找到了一个用于计算距离的半正弦函数
也许我的方法有问题?任何帮助表示赞赏。
以下适用于 BigQuery 标准 SQL
在这里,代码没有关注事件,而是脱离了经纬度,这大大减少了需要处理的量,从而避免了著名的 "Resources exceeded ..."
#standardSQL
CREATE TEMPORARY FUNCTION distance(lat1 FLOAT64, lon1 FLOAT64, lat2 FLOAT64, lon2 FLOAT64)
RETURNS FLOAT64 AS ((
WITH constants AS (
SELECT 0.017453292519943295 AS p
)
SELECT ROUND(12742 * ASIN(SQRT(
0.5 - COS((lat2 - lat1) * p)/2 +
COS(lat1 * p) * COS(lat2 * p) *
(1 - COS((lon2 - lon1) * p))/2)), 2)
FROM constants
));
WITH events AS (
SELECT *
FROM `gdelt-bq.full.events`
WHERE NOT(IFNULL(ActionGeo_Lat,0)=0 OR IFNULL(ActionGeo_Long,0)=0)
),
geos AS (
SELECT DISTINCT ActionGeo_CountryCode code, ActionGeo_Lat lat, ActionGeo_Long long
FROM events
)
SELECT c.code code, country, geo[safe_offset(0)].*
FROM (
SELECT code, ARRAY_AGG(STRUCT(dist, lat1, long1, lat2, long2) ORDER BY dist DESC LIMIT 1) AS geo
FROM (
SELECT e1.code code, e1.Lat lat1, e1.Long long1, e2.Lat lat2, e2.Long long2,
distance(e1.Lat, e1.Long, e2.Lat, e2.Long) dist
FROM geos e1
JOIN geos e2
ON e1.code = e2.code
AND e1.Lat > e2.Lat
)
GROUP BY code
) c
JOIN `gdelt-bq.extra.countryinfo` countries
ON c.code = countries.iso
-- ORDER BY dist DESC
作为输出示例(请耐心等待 - 我花了大约 12-13 分钟来 运行 以上查询)- 前 5 个国家(按距离)如下:
code country dist lat1 long1 lat2 long2
US United States 13468.78 18.1131 -65.3531 8.7318 167.74
MP Northern Mariana Islands 10508.24 16.0 146.0 -20.0 57.0
PF French Polynesia 9403.5 15.7833 111.2 6.339869976043701 -162.6750030517578
LS Lesotho 8741.97 47.2333 9.51667 -29.5 28.5
RS Serbia 8075.75 54.4922 168.12 43.4151 39.9248
注意:除了此处使用的距离函数,您还可以使用您选择的任何函数 - 例如,您可以使用您在问题中提到的 HAVERSINE 距离函数(无关紧要)
您还可以通过将 ARRAY_AGG() 中的 LIMIT 1 更改为 LIMIT 3 或任何您想要的数字来控制输出中的顶部距离数
我需要找到 所有 数据集中每个国家的事件点的最长距离。要获得有关国家/地区的信息,请加入 gdelt-bq:extra.countryinfo
。
所以现在我有了这个 table:
SELECT *
FROM [gdelt-bq:full.events] events JOIN
[gdelt-bq:extra.countryinfo] countries
ON events.Actor1CountryCode = countries.iso3
困难在于总共有大约50k个事件,一个组内最大为15K(对于美国),我需要先计算一个组内的所有距离(一个国家的事件),但是所有事件纬度和经度在一列中。所以我需要创建所有事件对来计算所有事件并找到最长的事件,对于最大的组来说,最长的是 15k 集中的 2 组合的数量,大约是 11kk。
顺便说一句,我在这里找到了一个用于计算距离的半正弦函数
也许我的方法有问题?任何帮助表示赞赏。
以下适用于 BigQuery 标准 SQL
在这里,代码没有关注事件,而是脱离了经纬度,这大大减少了需要处理的量,从而避免了著名的 "Resources exceeded ..."
#standardSQL
CREATE TEMPORARY FUNCTION distance(lat1 FLOAT64, lon1 FLOAT64, lat2 FLOAT64, lon2 FLOAT64)
RETURNS FLOAT64 AS ((
WITH constants AS (
SELECT 0.017453292519943295 AS p
)
SELECT ROUND(12742 * ASIN(SQRT(
0.5 - COS((lat2 - lat1) * p)/2 +
COS(lat1 * p) * COS(lat2 * p) *
(1 - COS((lon2 - lon1) * p))/2)), 2)
FROM constants
));
WITH events AS (
SELECT *
FROM `gdelt-bq.full.events`
WHERE NOT(IFNULL(ActionGeo_Lat,0)=0 OR IFNULL(ActionGeo_Long,0)=0)
),
geos AS (
SELECT DISTINCT ActionGeo_CountryCode code, ActionGeo_Lat lat, ActionGeo_Long long
FROM events
)
SELECT c.code code, country, geo[safe_offset(0)].*
FROM (
SELECT code, ARRAY_AGG(STRUCT(dist, lat1, long1, lat2, long2) ORDER BY dist DESC LIMIT 1) AS geo
FROM (
SELECT e1.code code, e1.Lat lat1, e1.Long long1, e2.Lat lat2, e2.Long long2,
distance(e1.Lat, e1.Long, e2.Lat, e2.Long) dist
FROM geos e1
JOIN geos e2
ON e1.code = e2.code
AND e1.Lat > e2.Lat
)
GROUP BY code
) c
JOIN `gdelt-bq.extra.countryinfo` countries
ON c.code = countries.iso
-- ORDER BY dist DESC
作为输出示例(请耐心等待 - 我花了大约 12-13 分钟来 运行 以上查询)- 前 5 个国家(按距离)如下:
code country dist lat1 long1 lat2 long2
US United States 13468.78 18.1131 -65.3531 8.7318 167.74
MP Northern Mariana Islands 10508.24 16.0 146.0 -20.0 57.0
PF French Polynesia 9403.5 15.7833 111.2 6.339869976043701 -162.6750030517578
LS Lesotho 8741.97 47.2333 9.51667 -29.5 28.5
RS Serbia 8075.75 54.4922 168.12 43.4151 39.9248
注意:除了此处使用的距离函数,您还可以使用您选择的任何函数 - 例如,您可以使用您在问题中提到的 HAVERSINE 距离函数(无关紧要)
您还可以通过将 ARRAY_AGG() 中的 LIMIT 1 更改为 LIMIT 3 或任何您想要的数字来控制输出中的顶部距离数