台风在变少,来香港的没有

文章目录

今天打开天气软件,大概率会看到薔琵(Champi,老挝提供的名字)在台湾以东洋面慢慢挪动,香港快运已经取消了明天十个班机。但如果你去拉香港天文台官方的热带气旋 best track(事后分析路径)数据集,41 年的记录里找不到它:这份数据叫 post analysis,事后分析,台风谢幕之后才归档。此刻在头顶上慢慢旋转的这团云,在数据世界里还不存在。

这件事本身比任何统计都更直观地说明数据的性质:它永远比现实慢一步。而在它慢的那一步之外,41 年、1038 个热带气旋的记录,足够回答一个每年夏天都会被问一遍的问题:台风到底在变多还是变少。

一、四十年的账本:总数和强度都在降

天文台官方的 best track 数据覆盖 1985 到 2025 年,西北太平洋和南海范围内共生成 1038 个热带气旋,年均 25.3 个。

按前后各二十年对比:

  • 总数:前二十年年均 26.6 个,后二十年 24.1 个
  • 达到台风级(Typhoon 及以上)的:从年均 15.8 个降到 12.6 个
  • 最多的年份是 1994 年,36 个;最少的是 2010 年,14 个

两个方向一致:海上的台风在变少,强的也在变少。「台风越来越猛」的直觉,在这份数据的总量和强度两个维度上都不成立。需要说明的是,这份数据只覆盖天文台的分析范围,且分析技术本身在四十年里有演进,跨四十年的精细对比要留一分余地。

二、但路过香港的,没有变少

真正反直觉的是第三条线:进入香港约 800 公里范围的热带气旋,前二十年年均 8.8 个,后二十年 9.3 个,不降反微升。而 2025 年这一年,有 15 个,是 41 年里最多的一次,超过 2013 年的 14 次和 2017 年的 13 次。

海上的总量在降,路过香港的却没降。一个可能的解释是路径分布的变化:台风生成的位置或移动路径整体偏移,使得进入华南沿海警戒范围的比例上升。这份数据能指出现象,但要归因到环流变化,需要更专业的气候分析,本文不下这个结论。

这里要把口径说清楚:800 公里是天文台一号戒备信号的官方范围(「有一热带气旋集结于香港约 800 公里的范围内,可能影响本港」)。天文台的官方博客专门解释过:即使风暴进入 800 公里范围,也不一定需要发出一号信号,要看移动速度、路径、强度、大风区范围综合判断。所以本文统计的是「进入警戒范围」,不等于「天文台发了信号」,两者不能互相替代。

三、八月是顶峰,夏天只有四个月

按生成月份统计 1038 个热带气旋,八月是绝对顶峰,226 个;七月到十月合计 736 个,占七成一。

一月到三月合计只有 36 个生成。所谓「台风季」,在这份数据里就是七月到十月这四个月,其余八个月是凑数的。这个分布也解释了为什么秋季台风总能成为新闻主角:十月的 148 个虽然比八月少,但碰上东北季风叠加,风雨往往比盛夏更难看。

四、极值与「同名不同台」

41 年里气压最低的是 2013 年的海燕(HAIYAN),890 百帕,最高风速 155 海里,达到超强台风级;2016 年的莫兰蒂(MERANTI)同为 890 百帕。路径最靠近香港的是 1997 年的维克托(VICTOR),最近时距港约 7 公里,基本是正面扑港。

讲这两个纪录要小心一个坑:台风名字是 140 个循环使用的,海燕这个名字在 41 年里出现过三次(2001、2007、2013)。只写「海燕 890 百帕」是错的,必须带年份。做同名统计时如果不按 JMA 编号而按名字分组,两个海燕会被合并成一个不存在的「超级海燕」。

五、这份数据的六个坑,我全踩了

把 41 个 CSV 拉下来解析的过程,比统计本身更值得写。

坑一:前三行是标题,不是表头。 每个文件开头三行分别是英文、繁体、简中的数据集名称,第四行才是表头。直接 read_csv 会把标题行当成数据。

坑二:表头是三语言斜杠分隔。 Tropical Cyclone Name/熱帶氣旋名稱/热带气旋名称,一个列名里三种语言。要按正斜杠切开取第一段,否则按中文列名取数直接 KeyError。

坑三:经纬度是 0.01 度单位。 数据里 840,12750 不是 840 度,是 8.40°N、127.50°E,要除以 100。忘了除,所有距离计算都是笑话。

坑四:时间是 UTC。 和香港时间差 8 小时,跨日期的路径点要留意。

坑五:1981 到 1984 的文件返回的是 HTML 错误页,不是 CSV。 文件名、状态码、体积都像正常响应,只有读内容才发现是 nginx 的 404 页。清理规则不能只看文件大小,要嗅探内容。这也是为什么本文的统计从 1985 年开始。

坑六:2026 年没有文件。 就是开头说的,事后分析还没发布。写脚本时如果假设「今年一定有」,循环会静默跳过一年,图表上凭空少一格。

还有两个数据特性值得知道:41 年里有 10 个热带气旋在数据里叫 nameless(有 JMA 编号但未命名);有 40 个路径点的强度标记为 LOW,是低于热带低压级的低压残余,集中在海燕、山神等 6 个气旋的衰减段。

六、怎么用这份数据

解析函数长这样,六个坑一次绕完:

python 复制代码
import csv, math
from pathlib import Path

def load_tc(year_dir):
    tcs = {}
    for f in sorted(Path(year_dir).glob("tc_*.csv")):
        lines = [ln for ln in f.read_text(encoding="utf-8-sig",
                                          errors="replace").splitlines()
                 if ln.strip()]
        hi = next(i for i, ln in enumerate(lines)
                  if ln.startswith("Tropical Cyclone Name"))
        hdr = next(csv.reader([lines[hi]]))
        ix = {c.split("/")[0]: i for i, c in enumerate(hdr)}   # 坑二
        for ln in lines[hi + 1:]:
            row = next(csv.reader([ln]))
            if len(row) < len(hdr):
                continue
            jma = row[ix["JMA Code"]].strip()
            t = tcs.setdefault(jma, {"name": row[ix["Tropical Cyclone Name"]].strip(),
                                     "pts": []})
            t["pts"].append((int(row[ix["Month"]]),
                             float(row[ix["Latitude (0.01 degree N)"]]) / 100,   # 坑三
                             float(row[ix["Longitude (0.01 degree E)"]]) / 100,
                             row[ix["Intensity"]].strip()))
    return tcs

def hav(lat1, lon1, lat2, lon2):
    R = 6371.0
    p1, p2 = math.radians(lat1), math.radians(lat2)
    a = (math.sin(math.radians(lat2 - lat1) / 2) ** 2
         + math.cos(p1) * math.cos(p2)
         * math.sin(math.radians(lon2 - lon1) / 2) ** 2)
    return 2 * R * math.asin(math.sqrt(a))

判断「是否进入香港 800km」,就是对每个气旋的所有路径点算一遍到(22.30°N, 114.17°E)的 Haversine 距离取最小值。这只是一种近似:把香港当成一个点,实际警戒范围是个以香港为中心的圆,且官方还要看路径趋势,不是只看距离。

七、慢一步的数据,和快一步的人

回到开头。今天头顶的薔琵不在这份数据里,明年的某个版本发布后,它才会有第一行记录。数据永远是滞后的,这是所有统计的宿命,也是它的价值所在:正因为 2025 年的 15 个已经归档,我们才知道「路过香港没变少」不是今年夏天的错觉,是四十年的结构。

台风季还剩最后一个月。今年会不会成为 41 年统计里的新极值,要等 post analysis 发布才知道。在那之前,看雷达比看数据集管用。

相关推荐
qq_406981031 小时前
大白话rust系列09 函数调用两次有什么错?
开发语言·python·rust
benchmark_cc2 小时前
QuantDash 安装成功后,如何验证 Python 环境可以正常导入 SDK?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
zh路西法3 小时前
【模型式强化学习】(二)PETS——从概率动力学模型到模型预测控制(MPC)
pytorch·python·强化学习·pe·mpc·ces·pets
Python自动化直播4 小时前
智能脚本批量管理拆开看:导入、导出、重写、试听
前端·python·ai·秒播
伤心的梧桐叶6 小时前
Picset与创客贴比等待时间,没做完的任务不能从表里消失
python
没有气的汽水7 小时前
一次 SQS 消费者静默退出的排查:问题最后竟然出在日志里
python
用户450030140237 小时前
物业催缴系统为什么总在"冷却"这一步翻车:账期建模与规则命中的几个取舍
python
Web极客码7 小时前
决策模型 + LLM:用 Python 拆解浏览器自动化工作流
java·python·自动化
fanruitian7 小时前
python 装饰器 闭包
python