---
title: FuXi-Det
canonical_url: "https://www.modelscope.cn/datasets/fuxiweather/FuXi-Det"
md_url: "https://www.modelscope.cn/datasets/fuxiweather/FuXi-Det.md"
repository: fuxiweather/FuXi-Det
chinese_name: "伏羲 0.1° 逐小时中期确定性预测"
last_updated: 2026-09-25
license: other
storage_size: "5.3 TB"
downloads: 28619
stars: 1
---

# FuXi-Det

> FuXi-Det - fuxiweather 在 ModelScope 开源的数据集。数据集为伏羲 0.1° 逐小时中期确定性预测，每天 2 次预测，每次预报未来 15 天。

fuxiweather/FuXi-Det 是 ModelScope 魔搭社区上的数据集，存储大小 5.3 TB，采用 other 许可。

- **Repository**: fuxiweather/FuXi-Det
- **License**: other
- **Storage size**: 5.3 TB
- **Downloads**: 28619
- **Stars**: 1
- **Last updated**: 2026-09-25

Source: https://www.modelscope.cn/datasets/fuxiweather/FuXi-Det

---

数据集文件元信息以及数据文件，请浏览“数据集文件”页面获取。

#### 下载方法 
:modelscope-code[]{type="sdk"}
:modelscope-code[]{type="git"}


# FuXi-Det 预报数据集 — 使用说明

本数据集存储区域天气预报场，每个起报时次打包为一个 `.tar` 归档文件。本说明覆盖数据的**解压**、使用 **`xarray` 读取**、**校验** 360 个预报步长文件，以及**可视化**方法。

## 数据集结构

- **仓库结构** — 根目录为扁平结构，每个起报时次对应一个归档文件：

  ```
  2025010100.tar
  2025010112.tar
  2025010200.tar
  ...
  ```

  文件名 `YYYYMMDDHH` 表示起报时次（UTC）。

- **每个归档文件内部** — 包含 360 个 NetCDF 文件，每个文件对应一个预报步长（lead time）：

  ```
  001.nc   # 预报步长 1
  002.nc   # 预报步长 2
  ...
  360.nc   # 预报步长 360
  ```

- **每个 `NNN.nc` 内部** — 包含一个 5 维数组：

  | 维度 | 大小 | 说明 |
  |------|------|------|
  | `time`    | 1    | 起报时次 |
  | `step`    | 1    | 预报步长（`001.nc` 对应 `1`，…，`360.nc` 对应 `360`） |
  | `channel` | 15   | 变量名（见下表） |
  | `lat`     | 361  | `54.0 → 18.0`，**降序**，间隔 0.1° |
  | `lon`     | 601  | `74.0 → 134.0`，升序，间隔 0.1° |

  数据变量名为 `__xarray_dataarray_variable__`。

  15 个通道（ERA5 风格短变量名）：

  | 通道 | 含义 | 通道 | 含义 |
  |------|------|------|------|
  | `MSL`   | 平均海平面气压 | `TCC`   | 总云量 |
  | `T2M`   | 2米温度 | `LCC`   | 低云量 |
  | `D2M`   | 2米露点温度 | `MCC`   | 中云量 |
  | `SST`   | 海表温度 | `HCC`   | 高云量 |
  | `U10M`  | 10米U风分量（东西向） | `SSRD`  | 向下表面太阳辐射 |
  | `V10M`  | 10米V风分量（南北向） | `FDIR`  | 地表直接太阳辐射 |
  | `U100M` | 100米U风分量（东西向） | `TP`    | 总降水量 |
  | `V100M` | 100米V风分量（南北向） |         | |

> **以下所有示例都依赖两个顺序注意事项：**
> 1. `lat` 为**降序**，因此范围切片应写为 `slice(high, low)`，例如 `lat=slice(40, 20)`。`lon` 为升序，因此写为 `lon=slice(100, 130)`。
> 2. `channel` 坐标**未排序**，因此选择通道时不要传入 `method="nearest"`。应先按精确名称选择通道，再仅对 `lat`/`lon` 使用 `method="nearest"`。

---

## 1. 解压归档文件

归档文件为普通（未压缩）的 `.tar` 文件。NetCDF4 内部已压缩，因此没有 gzip 压缩层。

**Shell：**

```bash
# 将一个起报时次解压到同名目录
mkdir -p 2025010100
tar -xf 2025010100.tar -C 2025010100/

# 解压当前目录下的所有归档文件
for t in *.tar; do
    mkdir -p "${t%.tar}"
    tar -xf "$t" -C "${t%.tar}/"
done
```

解压后会得到 `2025010100/001.nc … 2025010100/360.nc`。

**Python**（Python ≥ 3.12 中，`filter="data"` 是安全解压模式）：

```python
import tarfile
from pathlib import Path

def extract_archive(tar_path: str, out_dir: str) -> None:
    """Extract YYYYMMDDHH.tar into out_dir/ (creating it if needed)."""
    out = Path(out_dir)
    out.mkdir(parents=True, exist_ok=True)
    with tarfile.open(tar_path) as tar:
        tar.extractall(out, filter="data")

extract_archive("2025010100.tar", "2025010100")
```

---

## 2. 使用 `xarray` 读取

> 依赖: `xarray`, `netcdf4`, `matplotlib`.

`__xarray_dataarray_variable__` 名称较长，建议先绑定为常量。

### 单个文件（`001.nc`）

```python
import xarray as xr

VAR = "__xarray_dataarray_variable__"

ds = xr.open_dataset("2025010100/001.nc")
da = ds[VAR]                      # dims: (time, step, channel, lat, lon)

print(da.sizes)                   # {'time': 1, 'step': 1, 'channel': 15, ...}
print(da["channel"].values)       # ['MSL' 'T2M' ... 'TP']

t2m = da.sel(channel="T2M").isel(time=0, step=0)   # 一个 (lat, lon) 场
```

### 全部 360 个文件（一个完整起报时次）

360 个文件除 `step` 外共享所有坐标，因此可沿 `step` 维拼接，得到 `step = 1 … 360` 的数组。`open_mfdataset` 会惰性读取数据（仅在需要时加载数值），并依赖 `dask`：

```bash
pip install dask            # 基础依赖中不包含；仅 open_mfdataset 需要
```

```python
from pathlib import Path
import xarray as xr

VAR = "__xarray_dataarray_variable__"

def open_init_time(init_dir: str, expected_count: int = 360) -> xr.DataArray:
    """Open all NNN.nc files of one init-time as a single array (concat on step)."""
    files = step_files(init_dir, expected_count)          # 已校验，见 §3
    ds = xr.open_mfdataset(files, combine="nested", concat_dim="step")
    return ds[VAR]

da = open_init_time("2025010100")     # 当前维度: (time=1, step=360, channel=15, lat, lon)
```

> **没有 `dask`？** 可使用立即拼接方式，结果相同，但会将所有数据加载到内存：
> ```python
> da = xr.concat(
>     [xr.open_dataset(f)[VAR] for f in step_files("2025010100")],
>     dim="step",
> )
> ```

---

## 3. 校验 360 个预报步长文件

一个完整起报时次必须包含 `001.nc … 360.nc`。下面的辅助函数会按预报步长顺序列出文件，并在缺失文件时抛出清晰错误，指出缺失项。建议在读取或打包前调用。

```python
from pathlib import Path

def step_files(init_dir: str, expected_count: int = 360) -> list[Path]:
    """Return [001.nc .. NNN.nc] paths in order; raise if any are missing."""
    init = Path(init_dir)
    names = [f"{i:03d}.nc" for i in range(1, expected_count + 1)]
    missing = [n for n in names if not (init / n).is_file()]
    if missing:
        head = ", ".join(missing[:5])
        more = f" ... (+{len(missing) - 5} more)" if len(missing) > 5 else ""
        raise FileNotFoundError(
            f"{init}: expected {expected_count} files "
            f"(001.nc..{expected_count:03d}.nc), missing {len(missing)}: {head}{more}"
        )
    return [init / n for n in names]
```

```python
# 完整起报时次 -> 返回 360 个路径
files = step_files("2025010100")

# 不完整起报时次 -> 抛出清晰错误，例如：
# FileNotFoundError: 2025010100: expected 360 files (001.nc..360.nc),
#                    missing 359: 002.nc, 003.nc, 004.nc, 005.nc, 006.nc ... (+354 more)
```

> **本地测试说明：** 完整归档文件包含 360 个文件。若使用部分样例测试（例如仅有 `001.nc`），请传入 `expected_count=1`：
> `step_files("2025010100", expected_count=1)`。

---

## 4. 数据可视化

以下两个示例均假设已通过 [§2](#2-使用-xarray-读取) 得到 `da = open_init_time("2025010100")`，其维度为 `time, step, channel, lat, lon`。

### 指定经纬度点的时间序列

横轴为固定位置处的**预报步长**（lead time，1 … 360）。先按名称选择通道，再匹配最近的网格点：

```python
import matplotlib.pyplot as plt

series = (
    da.sel(channel="T2M")                          # 先精确匹配通道
      .sel(lat=30.0, lon=120.0, method="nearest")  # 匹配最近网格点
      .isel(time=0)
)

fig, ax = plt.subplots(figsize=(9, 3))
series.plot(ax=ax)                                 # 数值随预报步长变化
ax.set_title(f"T2M at lat={float(series.lat):.1f}, lon={float(series.lon):.1f}")
ax.set_xlabel("forecast step")
fig.tight_layout()
fig.savefig("t2m_timeseries.png", dpi=120)
```

### 指定经纬度范围的空间分布图

选择一个通道和一个预报步长后，对区域进行切片。注意 `lat` 为降序，应使用 `slice(high, low)`；`lon` 为升序：

```python
import matplotlib.pyplot as plt

field = (
    da.sel(channel="T2M")
      .sel(lat=slice(40, 20), lon=slice(100, 130))  # lat: high->low, lon: low->high
      .isel(time=0, step=0)                          # 第一个预报步长
)

fig, ax = plt.subplots(figsize=(6, 5))
field.plot(ax=ax)                                    # 填色图
ax.set_title("T2M — step 1")
fig.tight_layout()
fig.savefig("t2m_map.png", dpi=120)
```

若要绘制其他预报时效，可修改 `step`（0-based 索引）：`.isel(time=0, step=23)` 表示预报步长 24（`024.nc`）。
