跳到主要内容

分析数据

Tier0 采用 Marimo Notebook,支持使用 Python 进行高级数据分析。

创建 Notebook

  1. 登录 Tier0,然后选择 Notebook
编号项目说明
1分类按状态显示 Notebook。
2Notebook 树图以文件夹-文件层级结构列出 Notebook,支持添加 Notebook、刷新列表和搜索 Notebook。
3Notebook 列表详细显示所选文件夹下的所有 Notebook。
4导入导入 Notebook。
  1. 选择 > 新建文件夹
  1. 输入文件夹名称,然后单击 创建
  2. 单击已创建的文件夹,然后选择 > 新建 Notebook
  1. 输入 Notebook 信息,然后单击 创建
  2. 单击右侧已创建的 Notebook,开始编辑。
编号项目说明
1模块显示 Notebook 模块,包括数据源和变量、依赖包以及 AI 机器人。
2文件显示 Notebook 层级结构。
3画布显示单元格及对应结果。你可以选择创建不同类型的单元格、关闭 Notebook,以及修改 Notebook 设置。
4工具栏刷新单元格,并将 Notebook 保存为不同版本。
5Notebook 操作保存 Notebook。切换当前查看样式,包括单元格与结果或仅结果。停止或运行所有单元格。
6开发者模式进入开发者面板,并设置运行时活动。
7状态显示内存、CPU 和 AI 状态。

使用 Notebook 执行 SQL 查询

开始前须知

UNS 存储到数据库中的数据会作为 Notebook 中已有的数据源。

  1. 登录 Tier0,然后选择 Notebook
  2. 创建并进入一个 Notebook,单击左侧的 VARIABLES
  3. 在左侧找到需要的表,单击表名旁边的 ,自动生成 SQL 语句。
  1. 单击右下角的 ,运行所有单元格并查看查询结果。
提示
  • 你可以单击左侧 DATA SOURCES 下的 ,按需添加数据源。
  • 使用 Notebook 时可能缺少部分依赖包。此时,单击左侧的 Manage packages 进行安装。
  1. (可选)单击 SQL 添加新的单元格,然后选择已连接的数据库执行 SQL 语句。

使用 Notebook 分析数据

示例背景

  • 数据源是从工厂采集并发送到 Tier0 UNS 的设备温度和湿度。
  • 数据分析内容包括设置温湿度风险阈值、根据温湿度的组合数据识别风险,并生成表格和图表,便于查看。

操作步骤

  1. 登录 Tier0,然后选择 Notebook
  2. 创建一个 Notebook,并在其中添加以下单元格。
  • 单元格 1:导入库。
import marimo as mo
import pandas as pd
import altair as alt
  • 单元格 2:从数据库查询数据。
SELECT * FROM "uns"."device_15d9d69fd5eb" LIMIT 100
  • 单元格 3:清洗数据。

# 将SQL查询结果转成 pandas DataFrame
if hasattr(device_df, "to_pandas"):
df = device_df.to_pandas()
elif hasattr(device_df, "to_dicts"):
df = pd.DataFrame(device_df.to_dicts())
else:
df = pd.DataFrame(device_df)

# 清洗并准备数据
df["_timestamp"] = pd.to_datetime(df["_timestamp"])
df = df.sort_values("_timestamp").reset_index(drop=True)

df["temp"] = pd.to_numeric(df["temp"], errors="coerce")
df["humidity"] = pd.to_numeric(df["humidity"], errors="coerce")

df = df.dropna(subset=["temp", "humidity"])

df.head()
  • 单元格 4:设置风险阈值并生成风险状态字段。
temp_warning = mo.ui.slider(
start=0,
stop=100,
value=70,
label="Temperature warning threshold",
)

temp_critical = mo.ui.slider(
start=0,
stop=100,
value=85,
label="Temperature critical threshold",
)

humidity_warning = mo.ui.slider(
start=0,
stop=100,
value=70,
label="Humidity warning threshold",
)

humidity_critical = mo.ui.slider(
start=0,
stop=100,
value=85,
label="Humidity critical threshold",
)

mo.vstack([
mo.md("## Threshold Settings"),
mo.hstack([temp_warning, temp_critical]),
mo.hstack([humidity_warning, humidity_critical]),
])
  • 单元格 5:根据单元格 4 中设置的阈值,生成包含风险状态和异常状态的表格。
analyzed_df = df.copy()

def classify_risk(row):
temp = row["temp"]
humidity = row["humidity"]

temp_high = temp >= temp_warning.value
temp_critical_high = temp >= temp_critical.value

humidity_high = humidity >= humidity_warning.value
humidity_critical_high = humidity >= humidity_critical.value

if temp_critical_high and humidity_critical_high:
return "Critical: High temp + high humidity"
elif temp_critical_high:
return "Critical: High temperature"
elif humidity_critical_high:
return "Critical: High humidity"
elif temp_high and humidity_high:
return "Warning: Combined risk"
elif temp_high:
return "Warning: Temperature risk"
elif humidity_high:
return "Warning: Humidity risk"
else:
return "Normal"

analyzed_df["risk_status"] = analyzed_df.apply(classify_risk, axis=1)

analyzed_df["is_anomaly"] = analyzed_df["risk_status"] != "Normal"

analyzed_df.head()
  • 单元格 6:生成异常汇总统计信息。
total_count = len(analyzed_df)
anomaly_count = analyzed_df["is_anomaly"].sum()
normal_count = total_count - anomaly_count
anomaly_rate = anomaly_count / total_count * 100 if total_count > 0 else 0

critical_count = analyzed_df["risk_status"].str.startswith("Critical").sum()
warning_count = analyzed_df["risk_status"].str.startswith("Warning").sum()

mo.vstack([
mo.md("## Joint Anomaly Detection Summary"),
mo.hstack([
mo.stat(label="Total Records", value=f"{total_count}"),
mo.stat(label="Normal Records", value=f"{normal_count}"),
mo.stat(label="Warning Records", value=f"{warning_count}"),
mo.stat(label="Critical Records", value=f"{critical_count}"),
mo.stat(label="Anomaly Rate", value=f"{anomaly_rate:.1f}%"),
])
])
  • 单元格 7:生成柱状图,显示不同风险状态的分布。
risk_summary = (
analyzed_df
.groupby("risk_status")
.size()
.reset_index(name="count")
.sort_values("count", ascending=False)
)

risk_bar_chart = alt.Chart(risk_summary).mark_bar().encode(
x=alt.X("count:Q", title="Record Count"),
y=alt.Y("risk_status:N", sort="-x", title="Risk Status"),
tooltip=["risk_status", "count"]
).properties(
title="Risk Status Distribution",
width=700,
height=300
)

risk_bar_chart
  • 单元格 8:生成散点图,显示温度和湿度之间的关系,并按风险状态区分点的颜色。
scatter_chart = alt.Chart(analyzed_df).mark_circle(size=80, opacity=0.75).encode(
x=alt.X("temp:Q", title="Temperature"),
y=alt.Y("humidity:Q", title="Humidity"),
color=alt.Color("risk_status:N", title="Risk Status"),
tooltip=[
alt.Tooltip("_timestamp:T", title="Timestamp"),
alt.Tooltip("temp:Q", title="Temperature"),
alt.Tooltip("humidity:Q", title="Humidity"),
alt.Tooltip("risk_status:N", title="Risk Status"),
],
).properties(
title="Temperature and Humidity Joint Anomaly Detection",
width=700,
height=420,
)

temp_warning_line = alt.Chart(pd.DataFrame({"x": [temp_warning.value]})).mark_rule(
strokeDash=[6, 4]
).encode(
x="x:Q"
)

humidity_warning_line = alt.Chart(pd.DataFrame({"y": [humidity_warning.value]})).mark_rule(
strokeDash=[6, 4]
).encode(
y="y:Q"
)

scatter_chart + temp_warning_line + humidity_warning_line
  • 单元格 9:生成表格,显示异常记录详情。
anomaly_df = analyzed_df[analyzed_df["is_anomaly"]].copy()

anomaly_df = anomaly_df[
["_timestamp", "temp", "humidity", "risk_status"]
].sort_values("_timestamp")

mo.vstack([
mo.md("## Anomaly Details"),
mo.md(f"Detected **{len(anomaly_df)}** abnormal records based on the current thresholds."),
mo.ui.table(anomaly_df, page_size=10),
])
  • 单元格 10:生成分析结论摘要。
most_common_risk = (
risk_summary.iloc[0]["risk_status"]
if len(risk_summary) > 0
else "N/A"
)

mo.md(f"""
## Analysis Conclusion

Based on the current threshold settings:

- Total records analyzed: **{total_count}**
- Abnormal records detected: **{anomaly_count}**
- Overall anomaly rate: **{anomaly_rate:.1f}%**
- Warning records: **{warning_count}**
- Critical records: **{critical_count}**
- Most common status: **{most_common_risk}**

This analysis uses both temperature and humidity to identify equipment environment risks.
Compared with single-threshold monitoring, joint anomaly detection can better identify combined environmental risks, such as high temperature and high humidity occurring at the same time.
""")
  1. 单击右下角的 ,运行所有单元格并查看结果。
提示

在右上角的 VerticalGridSlides 中切换查看样式。

Are you ready to get started with Tier0?