SEISAMUSE

Jun Xie的博客

有趣的jupyter notebook插件:

插件名称 简介 官方链接
Jupyter Contrib NBe 核心扩展包,集成50+插件(代码补全、变量监控、执行时间显示等) GitHub
Hinterland 实时代码补全工具,支持 Python/R/Julia,减少拼写错误 文档
Table of Contents (2) 动态生成目录,支持标题跳转,适合长文档导航 配置页
Variable Inspector 侧边栏实时显示变量类型/大小/值,替代频繁 print(type) 操作 说明
ExecuteTime 记录每个 Cell 的执行时间和完成时间,优化性能分析 详情
Autopep8 一键格式化代码为 PEP8 标准,提升可读性 PyPI
jupyterthemes 界面主题美化,支持暗黑模式/护眼配色(如 monokai, solarized GitHub
Notify 内核空闲时发送浏览器通知,适合长时间任务(如模型训练) 文档
jupyter Widgets 创建交互控件(滑块/下拉菜单),将静态图表转为动态仪表盘 官网
Voilà 将 Notebook 转为独立 Web 应用,隐藏代码仅保留交互结果 文档
RISE 实时代码幻灯片工具,用 Markdown 标题分页,支持演示中修改参数 GitHub

安装:

1
2
3
pip install jupyter_contrib_nbextensions jupyterthemes voila rise
jupyter contrib nbextension install
jupyter nbextension enable [插件名] # 启用具体插件

  以下是有趣的新闻网站:

  • AllYouCanRead是一个综合性资讯导航平台,按地域聚合全球六大洲新闻站点,同时以艺术、商业、科技等超 30 个主题精细分类各类网站资源,杂志专区更细分动物、时尚、育儿等数十个品类,通过清晰的结构化导航,为用户提供一站式全球新闻媒体与实用网站的定向检索服务。
  • Apple News是苹果公司为iOS和macOS设备打造的官方新闻应用,它不仅整合主流新闻媒体的免费内容,还通过订阅服务 Apple News+ 提供大量杂志和深度报道。该平台以用户界面友好、内容精选优质而著称,尤其适合苹果生态中的用户日常阅读使用。借助苹果的算法推荐和编辑精选,用户可以在一个界面中阅读来自多家出版商的新闻、专题和评论。对于追求高品质阅读体验的用户,Apple News 提供了一种简洁但内容丰富的获取方式。
  • BBC News是英国广播公司旗下的新闻平台,长期以客观、权威的报道风格受到全球用户信赖。它提供来自全球各地的实时新闻、深度分析、专题报道以及视频广播内容,尤其擅长以多语种进行国际传播,包括提供中文页面服务。BBC News 无需订阅即可访问,内容涵盖政治、科技、文化、健康等广泛领域,适合希望获取权威信息、提升英文阅读能力或关注全球动态的广大读者。
  • CNN作为国际知名新闻平台,以实时追踪全球突发新闻为核心特色,24 小时不间断更新政治、经济、科技、文化及娱乐等领域资讯。其报道兼具速度与深度,既提供俄乌冲突、美国大选等热点事件的现场直击,也通过专家分析、纪录片等形式挖掘新闻背后的背景逻辑。
  • Flipboard是一个以“杂志式排版”为特色的新闻聚合与社交内容平台,用户可以根据自己的兴趣订阅特定主题、媒体或用户发布的内容源,并将喜欢的内容整理成属于自己的“杂志”。它强调视觉体验和内容个性化,非常适合喜欢图文并茂、轻松滑阅的移动端用户。Flipboard 支持离线阅读和多平台同步,并通过滑动式界面增强交互感,使其成为许多用户在通勤、碎片时间中快速获取资讯的理想选择。
  • Google News是谷歌推出的一项新闻聚合服务,它通过智能算法从全球各大新闻网站实时抓取内容,为用户推送个性化、主题化的新闻报道。平台聚合同一事件来自不同媒体的视角,帮助读者全面了解事件全貌。其界面简洁、使用免费,同时支持桌面和移动端,是获取国际主流新闻、快速了解时事动态的便捷工具。用户还可以设置感兴趣的主题或地区,实现高度定制化的阅读体验,非常适合需要快速掌握新闻全局的用户。
  • Newsnow作为一个英国的多元新闻聚合平台,具备诸多显著优势。其新闻内容丰富多元,广泛涵盖英国、世界、商业、娱乐、体育及科技等各个领域,能够满足不同用户的多样化阅读需求。网站的界面设计简洁直观,分类清晰,便于用户快速定位感兴趣的新闻板块。其个性化推荐功能有助于用户发现更多符合个人喜好的内容。
  • NewsBrief核心优势在于以分钟级速度聚合全球60+语言信源,通过AI驱动的动态聚类技术,将碎片化新闻提炼为可视化事件脉络,其独家”EU Focus”模块深度追踪28个欧盟机构政策动向,并支持跨事件对比分析,为政策研究者、商业机构提供学术级舆情洞察。
  • Newspaper Map通过地图可视化交互,直观聚合全球报纸资源,支持按地理位置一键直达各地新闻源,突破传统新闻检索的国界与语言限制。
  • Paperboy在算法推荐新闻泛滥的时代,反其道而行,成为”数字报亭式”的古典新闻聚合平台,满足用户对传统报纸阅读体验的怀旧需求,同时解决地方性信息获取痛点。
  • PressReader是一个汇集全球报纸和杂志的数字阅读平台,提供来自120多个国家、70多种语言的7000多份出版物原版内容。其最大优势在于内容全面、更新及时,涵盖新闻、财经、科技、时尚等多个领域。平台呈现与实体刊物一致的排版,支持全文搜索、多语种翻译、音频朗读与剪藏分享,提升了阅读的互动性和便捷性。
  • The New York Times是全球最具影响力的新闻机构之一,提供高质量的新闻报道、评论、深度专题和调查类文章。作为一个付费订阅平台,它以专业记者团队、深入独家的调查报道和精准的国际视角闻名,尤其在政治、经济、国际关系等领域具有广泛权威性。无论是通过网页还是手机 App,纽约时报为读者提供一种深入理解世界的方式,是重度新闻使用者、研究者和政策关注者的重要信息来源。
  • World News提供全球新闻资讯,整合大量知名媒体的报道,涵盖政治、经济、社会、文化及自然灾害等丰富多样的新闻内容,更新及时,能够快速反映世界各地的最新动态。该网站界面简洁直观,以图文列表形式展示新闻,每条新闻都明确标注了来源媒体和发布时间,增强了新闻的可信度与透明度。
  • 环球网国际新闻以 “全球视野、中国视角” 为核心,兼具时效性、权威性与多元覆盖,既关注国际政治经济格局的宏观变化,也聚焦与中国及华人相关的具体议题,通过结构化板块和图文结合的方式,为读者提供全面、及时的国际资讯。
  • 央视网作为国家级新媒体旗舰平台,既保持主流媒体的权威性,又通过技术创新实现“新闻+政务+服务”深度融合,是媒体融合发展的标杆案例。其核心优势在于依托总台内容资源库构建的全媒体传播体系,以及在无障碍访问等社会责任领域的先行实践。

  以下是$\LaTeX$的数学算符

说明:公式需包裹在 $...$(行内公式)或 $$...$$(块级公式)中,以下表格中的 渲染效果 需在支持 LaTeX 的 Markdown 环境中显示(如 Typora、Obsidian 等)。


一、基础运算符号

符号名称 $\LaTeX$ 命令 渲染效果
加号 a + b $a + b$
减号 a - b $a - b$
乘号(叉乘) a \times b $a \times b$
乘号(点乘) a \cdot b $a \cdot b$
除号 a \div b $a \div b$
加减号 a \pm b $a \pm b$
减加号 a \mp b $a \mp b$

二、关系运算符

符号名称 $\LaTeX$ 命令 渲染效果
等于 a = b $a = b$
不等于 a \neq b $a \neq b$
约等于 a \approx b $a \approx b$
大于等于 a \geq b $a \geq b$
小于等于 a \leq b $a \leq b$
远大于 a \gg b $a \gg b$
远小于 a \ll b $a \ll b$
正比于 a \propto b $a \propto b$

三、集合运算符

符号名称 $\LaTeX$ 命令 渲染效果
并集 A \cup B $A \cup B$
交集 A \cap B $A \cap B$
属于 x \in A $x \in A$
不属于 x \notin B $x \notin B$
子集 A \subset B $A \subset B$
真子集 A \subseteq B $A \subseteq B$
空集 \emptyset $\emptyset$
实数集 \mathbb{R} $\mathbb{R}$
自然数集 \mathbb{N} $\mathbb{N}$

四、微积分符号

符号名称 $\LaTeX$ 命令 渲染效果
积分 \int_{a}^{b} f(x) dx $\int_{a}^{b} f(x) dx$
偏导数 \frac{\partial f}{\partial x} $\frac{\partial f}{\partial x}$
极限 \lim_{x \to 0} \frac{\sin x}{x} $\lim_{x \to 0} \frac{\sin x}{x}$
求和 \sum_{i=1}^{n} i^2 $\sum_{i=1}^{n} i^2$
导数(撇号形式) f'(x) $f’(x)$
梯度 \nabla f $\nabla f$
二阶导数 \frac{d^2 y}{dx^2} $\frac{d^2 y}{dx^2}$

五、希腊字母

小写字母 $\LaTeX$ 命令 渲染效果 大写字母 LaTeX 命令 渲染效果
α (alpha) \alpha $\alpha$ Γ (Gamma) \Gamma $\Gamma$
β (beta) \beta $\beta$ Δ (Delta) \Delta $\Delta$
θ (theta) \theta $\theta$ Θ (Theta) \Theta $\Theta$
π (pi) \pi $\pi$ Π (Pi) \Pi $\Pi$
σ (sigma) \sigma $\sigma$ Σ (Sigma) \Sigma $\Sigma$

六、箭头符号

符号名称 $\LaTeX$ 命令 渲染效果
右箭头 \rightarrow $\rightarrow$
左箭头 \leftarrow $\leftarrow$
双向箭头 \leftrightarrow $\leftrightarrow$
蕴含符号 \Rightarrow $\Rightarrow$
等价符号 \Leftrightarrow $\Leftrightarrow$
映射箭头 \mapsto $\mapsto$

七、括号与定界符

符号名称 $\LaTeX$ 命令 渲染效果
圆括号(自适应) \left( \frac{a}{b} \right) $\left( \frac{a}{b} \right)$
方括号 \left[ x \right] $\left[ x \right]$
花括号 \left\{ x \right\} ${ x }$
绝对值 \lvert x \rvert $\lvert x \rvert$
范数 \lVert \mathbf{v} \rVert $\lVert \mathbf{v} \rVert$

八、矩阵环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$$ 
\begin{pmatrix} % 圆括号矩阵
a & b \\
c & d
\end{pmatrix}
\quad
\begin{bmatrix} % 方括号矩阵
a & b \\
c & d
\end{bmatrix}
\quad
\begin{vmatrix} % 行列式
a & b \\
c & d
\end{vmatrix}
$$

渲染效果:
$$
\begin{pmatrix} % 圆括号矩阵
a & b \
c & d
\end{pmatrix}
\quad
\begin{bmatrix} % 方括号矩阵
a & b \
c & d
\end{bmatrix}
\quad
\begin{vmatrix} % 行列式
a & b \
c & d
\end{vmatrix}
$$

看样子花括号和矩阵都不太行啊。

  以下是python脚本练习。其完成的功能包括:

  • 遍历目录events_20250619下所有子目录中以bhz.SAC_rm结尾的SAC文件;
  • 对这些数据进行窄带滤波,宽度为中心频率(周期分之一)的$\pm$5mHz,滤波器为4个极点0相位的Butterworth,滤波周期为arange(25,145,10);
  • 计算窄带滤波后的每个周期的信噪比。信噪比定义为信号窗口内,波形包络的最大值比上噪声窗口的均方根。信号窗口定义为2.5-5km/s的到时。噪声窗定义为信号末端之后1000秒开始的1000秒长度的窗口。计算的信噪比写入到user0;
  • 将处理后的数据写到新的文件夹bp_sac中,文件名命名为z.year.jday.00.STA.bhz.period,仅保留信噪比大于3的数据。
  • 采用并行处理(8个cpu)。
  • 统计每个周期信噪比大于3的波形数据。
  • 统计每个周期信噪比大于3的波形的平均信噪比。
  • 将统计结构写入csv,并画出统计结果。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    import os
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from obspy import read
    from obspy.signal.filter import envelope
    from concurrent.futures import ThreadPoolExecutor, as_completed
    from collections import defaultdict

    # 参数设置
    input_root = "events_20250619"
    output_root = "bp_sac"
    center_periods = np.arange(25, 150, 10)
    bandwidth = 0.010
    vmin, vmax = 2.5, 5.0
    noise_offset, noise_len = 1000, 1000
    snr_threshold = 3.0
    max_workers = 8 # 根据 CPU 核心数调整

    # 存储每个周期的 SNR 值
    period_snr_map = defaultdict(list)

    def process_file(filepath, root):
    results = []
    try:
    st = read(filepath)
    tr = st[0]
    sac = tr.stats.sac
    except Exception as e:
    print(f"跳过 {filepath}: {e}")
    return results

    if not hasattr(sac, "o") or not hasattr(sac, "dist"):
    return results

    dist = sac.dist
    starttime = tr.stats.starttime
    win_start = starttime + dist / vmax
    win_end = starttime + dist / vmin
    t = tr.times()
    abs_time = np.array([starttime + float(tt) for tt in t])

    for period in center_periods:
    fc = 1.0 / period
    fmin, fmax = fc - bandwidth / 2, fc + bandwidth / 2
    if fmin <= 0:
    continue
    tr_filt = tr.copy()
    tr_filt.detrend("demean")
    tr_filt.taper(0.05)
    tr_filt.filter("bandpass", freqmin=fmin, freqmax=fmax, corners=4, zerophase=True)
    env = envelope(tr_filt.data)
    idx_sig = np.where((abs_time >= win_start) & (abs_time <= win_end))[0]
    if len(idx_sig) == 0:
    continue
    signal_max = np.max(env[idx_sig])
    noise_start = win_end + noise_offset
    noise_end = noise_start + noise_len
    idx_noise = np.where((abs_time >= noise_start) & (abs_time <= noise_end))[0]
    if len(idx_noise) == 0:
    continue
    noise_rms = np.sqrt(np.mean(env[idx_noise] ** 2))
    snr = signal_max / noise_rms if noise_rms > 0 else 0

    if snr >= snr_threshold:
    tr_filt.stats.sac.user0 = snr
    year = tr.stats.starttime.year
    jday = tr.stats.starttime.julday
    station = tr.stats.station.lower()
    channel = tr.stats.channel.lower()
    outname = f"z.{year}.{jday:03d}.00.{station}.{channel}.{period:03d}"

    rel_dir = os.path.relpath(root, input_root)
    out_dir = os.path.join(output_root, rel_dir)
    os.makedirs(out_dir, exist_ok=True)
    outpath = os.path.join(out_dir, outname)
    tr_filt.write(outpath, format="SAC")

    results.append((period, snr))
    print(f"✔ 保存: {outname}, SNR={snr:.2f}")

    return results
    # ===== 收集所有文件路径 =====
    all_files = []
    for root, dirs, files in os.walk(input_root):
    for file in files:
    if file.endswith("bhz.SAC_rm"):
    all_files.append((os.path.join(root, file), root))

    print(f"📁 待处理文件数: {len(all_files)}")

    # ===== 并行处理 =====
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
    future_to_file = {executor.submit(process_file, fpath, root): (fpath, root) for fpath, root in all_files}
    for future in as_completed(future_to_file):
    try:
    result = future.result()
    for period, snr in result:
    period_snr_map[period].append(snr)
    except Exception as e:
    fpath, _ = future_to_file[future]
    print(f"❌ 文件出错 {fpath}: {e}")

    # ===== 统计与可视化 =====
    periods = sorted(period_snr_map.keys())
    counts = [len(period_snr_map[p]) for p in periods]
    means = [np.mean(period_snr_map[p]) if len(period_snr_map[p]) > 0 else 0 for p in periods]

    df = pd.DataFrame({
    "Period(s)": periods,
    "Count(SNR>3)": counts,
    "Mean_SNR(SNR>3)": means
    })
    df.to_csv("snr_stats.csv", index=False)

    # === 可视化 ===
    plt.figure(figsize=(10, 6))
    plt.bar(periods, counts, width=4, color='skyblue', edgecolor='black')
    plt.xlabel("Period (s)")
    plt.ylabel("Count of SNR > 3")
    plt.title("Number of Traces with SNR > 3 per Period")
    plt.grid(True, linestyle="--", alpha=0.5)
    plt.tight_layout()
    plt.savefig("snr_count_bar.png", dpi=150)

    plt.figure(figsize=(10, 6))
    plt.plot(periods, means, marker='o', linestyle='-', color='orange')
    plt.xlabel("Period (s)")
    plt.ylabel("Mean SNR (SNR > 3)")
    plt.title("Mean SNR of Traces with SNR > 3 per Period")
    plt.grid(True, linestyle="--", alpha=0.5)
    plt.tight_layout()
    plt.savefig("snr_mean_line.png", dpi=150)

    print("🎉 并行处理完成,统计结果写入 snr_stats.csv")

  安装了seisman的HinetPy,运行脚本数据下载脚本的时候就遇到这个问题:

1
2
3
4
5
6
from HinetPy import Client, win32
File "/home/junxie/work/Snet/HinetPy-main/HinetPy/__init__.py", line 23, in <module>
from .client import Client
File "/home/junxie/work/Snet/HinetPy-main/HinetPy/client.py", line 22, in <module>
from urllib3.util import create_urllib3_context
ImportError: cannot import name 'create_urllib3_context' from 'urllib3.util' (/home/junxie/.conda/envs/py3/lib/python3.9/site-packages/urllib3/util/__init__.py)

怎么整?

阅读全文 »

  数据下载好后需要统计下载的情况,这是python脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import os
from obspy import read
from datetime import datetime as dt
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.dates as mdates
from collections import defaultdict
from matplotlib.transforms import blended_transform_factory

# ===== 配置 =====
data_dir = "daily_waveforms" # 存放YYYYMMDD.mseed文件目录
station_file = "station.list" # 台站列表,格式:NET STA(两列)
components = ["LHZ", "LHN", "LHE"]
start_year = 2020
end_year = 2020

# ===== 读取台站列表 =====
stations = []
with open(station_file, "r") as f:
for line in f:
if line.strip():
net, sta = line.strip().split()[:2]
stations.append((net, sta))

station_set = set(f"{net}.{sta}" for net, sta in stations)

# ===== 初始化 =====
station_dates = {comp: defaultdict(set) for comp in components} # comp -> {net.sta -> set(date)}
station_file_sizes = defaultdict(int) # 台站对应所有文件大小
total_files = 0
total_file_size = 0

# ===== 遍历所有mseed文件 =====
all_files = sorted(f for f in os.listdir(data_dir) if f.endswith(".mseed"))
for filename in all_files:
filepath = os.path.join(data_dir, filename)

size = os.path.getsize(filepath)
total_files += 1
total_file_size += size

try:
st = read(filepath)
except Exception as e:
print(f"读取文件失败 {filename}: {e}")
continue

# 解析文件日期 YYYYMMDD
try:
file_date = dt.strptime(filename[:8], "%Y%m%d").date()
except Exception as e:
print(f"无法解析日期 {filename}: {e}")
continue

for tr in st:
net = tr.stats.network
sta = tr.stats.station
comp = tr.stats.channel[-3:]

key = f"{net}.{sta}"
if key not in station_set:
continue
if comp not in components:
continue

station_dates[comp][key].add(file_date)
station_file_sizes[key] += size

print(f"共计读取文件数: {total_files}")
print(f"所有文件总大小: {total_file_size / (1024**2):.2f} MB")

# ===== 删除无有效数据台站 =====
for comp in components:
keys_to_remove = [k for k, dates in station_dates[comp].items() if len(dates) == 0]
for k in keys_to_remove:
del station_dates[comp][k]

# ===== 输出有效天数统计文本 =====
for comp in components:
with open(f"station_day_count_{comp}.txt", "w") as f:
for key in sorted(station_dates[comp].keys()):
f.write(f"{key} {len(station_dates[comp][key])}\n")

# ===== 台网颜色映射 =====
all_nets = sorted(set(net for net, sta in stations))
net_color_map = {net: cm.get_cmap("tab20")(i / max(len(all_nets)-1,1)) for i, net in enumerate(all_nets)}

# ===== 绘图函数 =====
def plot_component_availability(comp, station_dates_comp):
valid_stations = sorted(station_dates_comp.keys(), key=lambda x: (x.split(".")[0], x.split(".")[1]))
fig, ax = plt.subplots(figsize=(14, max(6, 0.3 * len(valid_stations))))

def to_datetime(d):
return dt(d.year, d.month, d.day)

for idx, key in enumerate(valid_stations):
net = key.split(".")[0]
dates = sorted(station_dates_comp[key])
x_vals = [to_datetime(d) for d in dates]
ax.plot(x_vals, [idx]*len(dates), ".", color=net_color_map[net], markersize=2)

ax.set_xlabel("时间")
ax.set_ylabel("台站")
ax.set_yticks(range(len(valid_stations)))
ax.set_yticklabels(valid_stations, fontsize=5)

ax.grid(True, linestyle=":", alpha=0.5)

x_start = dt(start_year, 1, 1)
x_end = dt(end_year, 12, 31)
ax.set_xlim(x_start, x_end)

ax.xaxis.set_major_locator(mdates.YearLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y"))

plt.tight_layout(rect=[0, 0, 0.85, 1])

# 右侧外部标注台网名
trans = blended_transform_factory(ax.transAxes, ax.transData)
net_indices = defaultdict(list)
for idx, key in enumerate(valid_stations):
net = key.split(".")[0]
net_indices[net].append(idx)

for net, indices in net_indices.items():
mid_idx = indices[len(indices)//2]
color = net_color_map[net]
ax.text(1.02, mid_idx, net, color=color, fontsize=8, fontweight='bold',
verticalalignment='center', horizontalalignment='left',
transform=trans)

plt.savefig(f"{comp}_availability_2013_2022.png", dpi=300, bbox_inches='tight')
plt.close()
print(f"已保存图像: {comp}_availability_2013_2022.png")

# ===== 画三分量图 =====
for comp in components:
plot_component_availability(comp, station_dates[comp])

# ===== 台网统计 =====
network_stats = defaultdict(lambda: {"total": 0, "valid": 0, "day_counts": []})

for net, sta in stations:
network_stats[net]["total"] += 1

all_valid_keys = set()
for comp in components:
all_valid_keys.update(station_dates[comp].keys())

for key in all_valid_keys:
net = key.split(".")[0]
days_list = [len(station_dates[comp].get(key, [])) for comp in components]
valid_days = max(days_list)
network_stats[net]["valid"] += 1
network_stats[net]["day_counts"].append(valid_days)

print("\n台网统计汇总:")
print(f"{'Net':<6} {'Total':>6} {'Valid':>6} {'AvgDays':>10}")
print("-" * 32)
with open("network_summary_all_components.txt", "w") as f:
f.write(f"{'Net':<6} {'Total':>6} {'Valid':>6} {'AvgDays':>10}\n")
for net in sorted(network_stats.keys()):
total = network_stats[net]["total"]
valid = network_stats[net]["valid"]
avg_days = np.mean(network_stats[net]["day_counts"]) if network_stats[net]["day_counts"] else 0
line = f"{net:<6} {total:>6} {valid:>6} {avg_days:>10.1f}"
print(line)
f.write(line + "\n")

# ===== 总结 =====
print(f"\n文件总数: {total_files}")
print(f"文件总大小: {total_file_size/(1024**2):.2f} MB ({total_file_size/(1024**3):.2f} GB)")

  这个脚本实现的功能包括:

  • 统计开始时间start_year到结束时间end_year的数据下载情况
  • 对LHZ、LHN和LHE分别进行统计。
  • 对统计结果进行可视化输出。
  • 横轴是时间,纵轴是台站名。不同台网用不同颜色标出。在图右侧标出台网名。
  • 输出文件network_summary_all_components.txt,给出台网包含台站数目,有效台站数目和各自平均天数。
  • 输出文件station_day_count_{comp}.txt,给出台站名和有效天数。
  • 输出文件总数,文件总大小。
0%