MNE-Python 第8天学习笔记:时频分析(ERD/ERS)

一、什么是时频分析?

1.1 ERP 的局限性

python 复制代码
到目前为止,我们做的是 ERP 分析:

ERP = 时间 × 振幅
      ↑
   只保留了时间信息
   频率信息被叠加平均"抹掉"了

问题:
  大脑的某些活动不是"时间锁定"的
  而是"频率锁定"的
  
  比如:闭眼后 Alpha 波增强
       这个变化在时间上不是精确对准的
       但在频率上非常明显(8-13Hz)

1.2 时频分析的原理

python 复制代码
时频分析 = 时间 × 频率 × 功率
           ↑      ↑       ↑
        什么时候 什么频率 多强

就像看乐谱:
  横轴是时间(第几秒)
  纵轴是频率(什么音高)
  颜色是强度(多大声)

时频分析就是给脑电信号写"乐谱"!

1.3 什么是 ERD/ERS?

python 复制代码
ERD = Event-Related Desynchronization(事件相关去同步)
ERS = Event-Related Synchronization(事件相关同步)

概念:
  大脑在静息时,神经元有一定程度的同步活动
  当某个脑区被"激活"时:
    神经元开始各自工作 → 同步性下降 → ERD(功率降低)
  当某个脑区被"抑制"时:
    神经元同步活动增强 → ERS(功率升高)

计算方式:
  ERD/ERS = (刺激后功率 - 基线功率) / 基线功率 × 100%
  
  正值(ERS)= 功率升高 = 同步增强
  负值(ERD)= 功率降低 = 去同步(活跃)

二、环境准备与数据加载

2.1 导入库

python 复制代码
# ========== 环境设置 ==========

# matplotlib.use('TkAgg'):
#   设置 matplotlib 的后端为 TkAgg
#   TkAgg 基于 Tkinter,Windows 自带,无需额外安装
#   必须在 import pyplot 之前设置
import matplotlib
matplotlib.use('TkAgg')

# pyplot:matplotlib 的绘图接口
import matplotlib.pyplot as plt

# mne:脑电分析核心库
import mne

# numpy:科学计算库
# np 是约定俗成的简写
import numpy as np

# os:操作系统路径处理
import os

# warnings:警告控制
import warnings
warnings.filterwarnings('ignore')

# ========== 中文字体设置 ==========
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False

print("="*60)
print("MNE-Python 第8天:时频分析(ERD/ERS)")
print("="*60)

2.2 加载数据并预处理

python 复制代码
# ---------- 1. 加载数据并预处理 ----------
sample_data_folder = mne.datasets.sample.data_path()
raw_fname = os.path.join(sample_data_folder, 'MEG', 'sample', 'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(raw_fname, preload=False)

# 提取 EEG + EOG + STIM 通道
raw_eeg = raw.copy().pick_types(eeg=True, eog=True, stim=True)

# 重命名通道(第2天的知识)
eeg_names = [ch for ch in raw_eeg.ch_names if ch.startswith('EEG')]
montage = mne.channels.make_standard_montage('standard_1020')
standard_names = montage.ch_names[:len(eeg_names)]
raw_eeg.rename_channels(dict(zip(eeg_names, standard_names)))
raw_eeg.set_montage(montage)

# 加载到内存
raw_eeg.load_data()

# 滤波
raw_eeg.notch_filter(freqs=60, picks='eeg', verbose=False)
raw_eeg.filter(l_freq=1, h_freq=40, picks='eeg', verbose=False)
raw_eeg.set_eeg_reference('average', verbose=False)
print("✅ 数据预处理完成")

# 查看可用通道
eeg_chs = [ch for ch in raw_eeg.ch_names 
           if raw_eeg.get_channel_types(picks=[ch])[0] == 'eeg']
print(f"可用 EEG 通道: {len(eeg_chs)} 个")

2.3 提取事件和创建 Epochs

python 复制代码
# ---------- 2. 提取事件和创建 Epochs ----------

# 提取事件
events = mne.find_events(raw_eeg, stim_channel='STI 014')

# 事件 ID 字典
event_id = {
    '听觉/左耳': 1,
    '听觉/右耳': 2,
    '视觉/左眼': 3,
    '视觉/右眼': 4
}

# 时频分析需要更长的分段
# 为什么?
#   低频信号(如 4Hz)一个周期就需要 250ms
#   如果分段太短,低频信息会丢失
#   通常需要 ±1 秒或更长
epochs = mne.Epochs(
    raw_eeg,
    events,
    event_id=event_id,
    tmin=-1.0,           # 刺激前 1 秒(比 ERP 分析更长)
    tmax=2.0,            # 刺激后 2 秒(比 ERP 分析更长)
    baseline=(-0.5, 0),  # 用刺激前 0.5 秒做基线
    reject=dict(eeg=150e-6),
    preload=True,
    verbose=False
)

print(f"✅ Epochs 创建完成: {len(epochs)} 个分段")
print(f"  时间范围: {epochs.times[0]:.1f} ~ {epochs.times[-1]:.1f} 秒")
print(f"  分段时长: {epochs.times[-1] - epochs.times[0]:.1f} 秒")

时频分析的 Epochs 为什么更长?

python 复制代码
ERP 分析的 Epochs:
  -0.2s ─── 0s ───────── 0.5s
  只需看到刺激后的即时反应

时频分析的 Epochs:
  -1.0s ───────── 0s ───────────── 2.0s
  需要看到:
    1. 刺激前足够长的基线(计算 ERD/ERS 需要)
    2. 刺激后低频成分的完整变化
    3. 频率越低,需要的时长越长

三、选择感兴趣通道

python 复制代码
# ---------- 3. 选择通道 ----------
print("\n选择感兴趣通道...")

# 时频分析通常关注特定脑区
# 运动想象:C3, C4, Cz(运动皮层)
# 听觉:T7, T8(颞叶)
# 视觉:O1, O2, Oz(枕叶)

# 选择实际存在的通道
desired_channels = ['Cz', 'C3', 'C4', 'Fz', 'Pz']
available_channels = [ch for ch in desired_channels if ch in eeg_chs]

if len(available_channels) == 0:
    # 如果想要的通道都不存在,用前几个
    available_channels = eeg_chs[:5]

print(f"  想要的通道: {desired_channels}")
print(f"  可用的通道: {available_channels}")

# 从 epochs 中只选择这些通道
epochs_tfr = epochs.copy().pick(available_channels)
print(f"  ✅ 选择了 {len(epochs_tfr.ch_names)} 个通道用于时频分析")

四、Morlet 小波变换

4.1 什么是小波变换?

python 复制代码
傅里叶变换 vs 小波变换:

傅里叶变换:
  把信号分解为不同频率的正弦波
  但失去时间信息
  
  信号:  ┌─┐   ┌─┐
        ─┘ └───┘ └───
  傅里叶: "包含 5Hz 和 10Hz"
         "但不知道什么时候出现"

小波变换:
  用小波(一段波形)在时间上滑动
  同时保留时间和频率信息
  
  信号:  ┌─┐   ┌─┐
        ─┘ └───┘ └───
  小波:  "0-1秒: 5Hz 很强"
         "1-2秒: 10Hz 很强"

4.2 Morlet 小波

python 复制代码
# Morlet 小波 = 正弦波 × 高斯窗
# 
# 正弦波部分:提供频率信息
# 高斯窗部分:限制时间范围
#
# 参数 n_cycles(周期数)控制时间-频率的平衡:
#   n_cycles 大 → 频率分辨率高,时间分辨率低
#   n_cycles 小 → 时间分辨率高,频率分辨率低

4.3 代码实现

python 复制代码
# ---------- 4. Morlet 小波变换 ----------
print("\n" + "="*60)
print("Morlet 小波时频分析")
print("="*60)

# 定义要分析的频率范围
# Alpha 波:8-13 Hz(放松)
# Beta 波:13-30 Hz(活跃/运动想象)
# 这里分析 4-30 Hz
frequencies = np.arange(4, 31, 1)  # 4, 5, 6, ..., 30 Hz
# np.arange(起始, 终止, 步长)
# 注意:终止值不包含在内,所以是 4~30

# 每个频率的小波周期数
# n_cycles = frequencies / 2
# 低频用少周期(如 4Hz 用 2 个周期)
# 高频用多周期(如 30Hz 用 15 个周期)
# 这样可以平衡时间-频率分辨率
n_cycles = frequencies / 2

print(f"频率范围: {frequencies[0]} ~ {frequencies[-1]} Hz")
print(f"频率数量: {len(frequencies)}")
print(f"周期数范围: {n_cycles[0]:.1f} ~ {n_cycles[-1]:.1f}")

# tfr_morlet():使用 Morlet 小波计算时频表示
# 
# 参数详解:
#   epochs_tfr:要分析的 Epochs 数据
#   freqs:要分析的频率列表
#   n_cycles:每个频率的小波周期数
#   return_itc:是否返回相位一致性(ITC)
#   average:是否对所有分段取平均
#   decim:降采样因子(每隔 N 个时间点取一个,减少数据量)
power = mne.time_frequency.tfr_morlet(
    epochs_tfr,                # 输入数据
    freqs=frequencies,         # 频率列表
    n_cycles=n_cycles,         # 周期数
    return_itc=False,          # 不计算 ITC(只计算功率)
    average=True,              # 对所有分段取平均
    decim=2,                   # 降采样(每隔2个点取1个)
    n_jobs=1,                  # 并行计算的核心数
    verbose=False              # 不打印详细信息
)

print(f"✅ 时频分析完成")
print(f"  功率数据形状: {power.data.shape}")
print(f"    (通道数, 频率数, 时间点数) = {power.data.shape}")

tfr_morlet() 参数详解:

五、时频图可视化

5.1 单通道时频图

python 复制代码
print("\n" + "="*60)
print("时频图可视化")
print("="*60)

# plot():绘制时频图
# 
# 横轴:时间(秒)
# 纵轴:频率(Hz)
# 颜色:功率(dB)或 ERD/ERS(%)
# 
# baseline 参数:基线校正
#   baseline=(-0.5, 0):用刺激前 0.5 秒做基线
#   mode='percent':显示为相对于基线的百分比变化
#   → ERD/ERS 图!

print("1. 绘制 Cz 通道的时频图...")
fig = power.plot(
    picks='Cz',                 # Cz 通道(头顶中央)
    baseline=(-0.5, 0),        # 基线范围
    mode='percent',             # 显示为百分比变化
    vmin=-50,                   # 颜色范围最小值
    vmax=50,                    # 颜色范围最大值
    title='Cz 通道 ERD/ERS',
    show=True
)
plt.show(block=True)

时频图怎么看?

python 复制代码
    频率 (Hz)
    30 ┤  ░░                     ░░
       │ ░░░░        ░░░░       ░░░░
    20 ┤ ░░░░░      ░░░░░░     ░░░░░
       │ ░░░░░░    ░░░░░░░░   ░░░░░░░
    10 ┤ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
       │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
     4 ┤────────────────────────────────
      -1.0    -0.5    0    0.5   1.0   1.5   2.0
                  ↑
               刺激点
               
    颜色含义(mode='percent'):
      红色 = ERS(功率升高 > 基线)
      蓝色 = ERD(功率降低 < 基线)
      
    典型模式:
      Alpha 频段(8-13Hz):
        刺激后出现 ERD(蓝色)
        = 大脑活跃,Alpha 被抑制
      Beta 频段(13-30Hz):
        刺激后可能出现 ERS(红色)
        = 运动相关同步

5.2 多通道时频图

python 复制代码
print("\n2. 绘制所有选中通道的时频图...")

# 对每个可用通道绘制时频图
fig, axes = plt.subplots(
    len(available_channels), 1,     # 行数 = 通道数
    figsize=(12, 3 * len(available_channels))
)

# 确保 axes 是数组(如果只有一个通道)
if len(available_channels) == 1:
    axes = [axes]

for idx, ch_name in enumerate(available_channels):
    power.plot(
        picks=ch_name,
        baseline=(-0.5, 0),
        mode='percent',
        vmin=-50, vmax=50,
        axes=axes[idx],
        show=False,
        colorbar=False if idx < len(available_channels) - 1 else True
    )
    axes[idx].set_title(f'{ch_name} ERD/ERS', fontsize=12)

plt.suptitle('多通道时频图对比', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.savefig('day8_multichannel_tfr.png', dpi=150, bbox_inches='tight')
print("✅ 多通道时频图已保存")
plt.show(block=True)

六、ERD/ERS 地形图

6.1 什么是 ERD/ERS 地形图?

python 复制代码
时频图 = 单个通道的 时间×频率 图
ERD/ERS 地形图 = 某个频率、某个时间,头皮上的 ERD/ERS 分布

相当于把时频图上的一个"像素"展开为整个头皮的地图

6.2 代码实现

python 复制代码
print("\n" + "="*60)
print("ERD/ERS 地形图")
print("="*60)

# plot_topo():绘制地形图 × 时间序列
# 每一行是一个通道的时频图
# 顶部是在特定时间点的地形图

print("绘制 ERD/ERS 地形图...")
fig = power.plot_topo(
    baseline=(-0.5, 0),       # 基线范围
    mode='percent',            # 百分比变化
    vmin=-50, vmax=50,        # 颜色范围
    title='ERD/ERS 地形图',
    show=True
)
plt.show(block=True)

七、不同条件的 ERD/ERS 对比

7.1 分条件计算

python 复制代码
print("\n" + "="*60)
print("不同条件的 ERD/ERS 对比")
print("="*60)

# 对每个条件分别计算时频分析
power_dict = {}

for cond_name in ['听觉/左耳', '视觉/左眼']:
    print(f"\n计算 {cond_name} 的时频分析...")
    
    # 筛选该条件的分段
    epochs_cond = epochs_tfr[cond_name]
    print(f"  分段数: {len(epochs_cond)}")
    
    # Morlet 小波变换
    power_cond = mne.time_frequency.tfr_morlet(
        epochs_cond,
        freqs=frequencies,
        n_cycles=n_cycles,
        return_itc=False,
        average=True,
        decim=2,
        verbose=False
    )
    
    power_dict[cond_name] = power_cond

print("✅ 各条件时频分析完成")

7.2 对比可视化

python 复制代码
print("\n绘制听觉 vs 视觉的 ERD/ERS 对比...")

fig, axes = plt.subplots(1, 2, figsize=(16, 6))
fig.suptitle('听觉 vs 视觉 ERD/ERS(Cz通道)', fontsize=14, fontweight='bold')

for idx, (cond_name, power_cond) in enumerate(power_dict.items()):
    power_cond.plot(
        picks='Cz',
        baseline=(-0.5, 0),
        mode='percent',
        vmin=-50, vmax=50,
        axes=axes[idx],
        show=False
    )
    axes[idx].set_title(cond_name, fontsize=12)

plt.tight_layout()
plt.savefig('day8_condition_comparison.png', dpi=150, bbox_inches='tight')
print("✅ 条件对比图已保存")
plt.show(block=True)

八、提取特定频段的 ERD/ERS 时间序列

8.1 代码实现

python 复制代码
print("\n" + "="*60)
print("提取特定频段的 ERD/ERS 时间序列")
print("="*60)

# 有时候我们只关心某个特定频段
# 比如 Alpha 频段(8-13 Hz)

# 从功率数据中提取 Alpha 频段
alpha_freqs = (frequencies >= 8) & (frequencies <= 13)
# alpha_freqs 是一个布尔数组
# [False, False, False, False, True, True, True, True, True, True, False, ...]
#  ↑4Hz  ↑5Hz  ↑6Hz  ↑7Hz  ↑8Hz  ↑9Hz  ↑10Hz ↑11Hz ↑12Hz ↑13Hz ↑14Hz

# 对 Alpha 频段的功率取平均
alpha_power = power.data[:, alpha_freqs, :].mean(axis=1)
# 结果形状:(通道数, 时间点数)

print(f"Alpha 频段: 8-13 Hz")
print(f"Alpha 功率形状: {alpha_power.shape}")

# 绘制 Alpha ERD/ERS 时间序列
fig, ax = plt.subplots(figsize=(12, 6))

# 获取时间数组
times = power.times

# 绘制每个通道的 Alpha ERD/ERS
for idx, ch_name in enumerate(power.ch_names):
    # 计算相对于基线的百分比变化
    baseline_idx = (times >= -0.5) & (times <= 0)
    baseline_mean = alpha_power[idx, baseline_idx].mean()
    
    # ERD/ERS = (功率 - 基线) / 基线 × 100%
    erd_ers = (alpha_power[idx, :] - baseline_mean) / baseline_mean * 100
    
    ax.plot(times, erd_ers, label=ch_name, linewidth=1.5, alpha=0.8)

ax.axvline(x=0, color='red', linestyle='--', alpha=0.5, label='刺激点')
ax.axhline(y=0, color='black', linestyle='-', alpha=0.3)
ax.set_xlabel('时间 (秒)', fontsize=12)
ax.set_ylabel('ERD/ERS (%)', fontsize=12)
ax.set_title('Alpha 频段 (8-13 Hz) ERD/ERS 时间序列', fontsize=14, fontweight='bold')
ax.legend(fontsize=8, loc='upper right')
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('day8_alpha_erd_ers.png', dpi=150, bbox_inches='tight')
print("✅ Alpha ERD/ERS 时间序列已保存")
plt.show(block=True)

ERD/ERS 时间序列解读:

python 复制代码
Alpha ERD/ERS (%)

  +50 │    ERS(同步增强)
      │    ← 通常在闭眼或放松时出现
  +25 │
    0 ┼──────────────────────→ 时间
  -25 │         ╲
      │          ╲___ ← ERD(去同步)
  -50 │               ← 大脑活跃时 Alpha 被抑制
      └──────────────────────────
      -1.0    0    1.0    2.0

刺激后 Alpha ERD 的解释:
  刺激引起大脑活跃 → Alpha 被抑制
  → 出现负的百分比变化(ERD)
  
刺激后 Alpha ERS 的解释:
  刺激后大脑恢复静息 → Alpha 反弹
  → 出现正的百分比变化(ERS)

九、Beta 频段分析

python 复制代码
print("\n" + "="*60)
print("Beta 频段 ERD/ERS")
print("="*60)

# 提取 Beta 频段(13-30 Hz)
beta_freqs = (frequencies >= 13) & (frequencies <= 30)
beta_power = power.data[:, beta_freqs, :].mean(axis=1)

print(f"Beta 频段: 13-30 Hz")

# 绘制 Beta ERD/ERS 时间序列
fig, ax = plt.subplots(figsize=(12, 6))

times = power.times

for idx, ch_name in enumerate(power.ch_names):
    baseline_idx = (times >= -0.5) & (times <= 0)
    baseline_mean = beta_power[idx, baseline_idx].mean()
    erd_ers = (beta_power[idx, :] - baseline_mean) / baseline_mean * 100
    ax.plot(times, erd_ers, label=ch_name, linewidth=1.5, alpha=0.8)

ax.axvline(x=0, color='red', linestyle='--', alpha=0.5, label='刺激点')
ax.axhline(y=0, color='black', linestyle='-', alpha=0.3)
ax.set_xlabel('时间 (秒)', fontsize=12)
ax.set_ylabel('ERD/ERS (%)', fontsize=12)
ax.set_title('Beta 频段 (13-30 Hz) ERD/ERS 时间序列', fontsize=14, fontweight='bold')
ax.legend(fontsize=8, loc='upper right')
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('day8_beta_erd_ers.png', dpi=150, bbox_inches='tight')
print("✅ Beta ERD/ERS 时间序列已保存")
plt.show(block=True)

十、第8天完整代码

python 复制代码
# ========== 环境设置 ==========
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import mne
import numpy as np
import os
import warnings
warnings.filterwarnings('ignore')

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False

print("="*60)
print("MNE-Python 第8天:时频分析(ERD/ERS)")
print("="*60)

# ---------- 1. 加载数据并预处理 ----------
sample_data_folder = mne.datasets.sample.data_path()
raw_fname = os.path.join(sample_data_folder, 'MEG', 'sample', 'sample_audvis_raw.fif')
raw = mne.io.read_raw_fif(raw_fname, preload=False)

raw_eeg = raw.copy().pick_types(eeg=True, eog=True, stim=True)
eeg_names = [ch for ch in raw_eeg.ch_names if ch.startswith('EEG')]
montage = mne.channels.make_standard_montage('standard_1020')
standard_names = montage.ch_names[:len(eeg_names)]
raw_eeg.rename_channels(dict(zip(eeg_names, standard_names)))
raw_eeg.set_montage(montage)
raw_eeg.load_data()
raw_eeg.notch_filter(freqs=60, picks='eeg', verbose=False)
raw_eeg.filter(l_freq=1, h_freq=40, picks='eeg', verbose=False)
raw_eeg.set_eeg_reference('average', verbose=False)
print("✅ 数据预处理完成")

# 查看可用通道
eeg_chs = [ch for ch in raw_eeg.ch_names 
           if raw_eeg.get_channel_types(picks=[ch])[0] == 'eeg']

# ---------- 2. 提取事件和创建 Epochs ----------
events = mne.find_events(raw_eeg, stim_channel='STI 014')
event_id = {'听觉/左耳': 1, '听觉/右耳': 2, '视觉/左眼': 3, '视觉/右眼': 4}

epochs = mne.Epochs(raw_eeg, events, event_id=event_id,
                    tmin=-1.0, tmax=2.0, baseline=(-0.5, 0),
                    reject=dict(eeg=150e-6), preload=True, verbose=False)
print(f"✅ Epochs: {len(epochs)} 个分段")

# ---------- 3. 选择通道 ----------
desired_channels = ['Cz', 'C3', 'C4', 'Fz', 'Pz']
available_channels = [ch for ch in desired_channels if ch in eeg_chs]
if len(available_channels) == 0:
    available_channels = eeg_chs[:5]
epochs_tfr = epochs.copy().pick(available_channels)
print(f"✅ 选择通道: {available_channels}")

# ---------- 4. Morlet 小波变换 ----------
frequencies = np.arange(4, 31, 1)
n_cycles = frequencies / 2

power = mne.time_frequency.tfr_morlet(
    epochs_tfr, freqs=frequencies, n_cycles=n_cycles,
    return_itc=False, average=True, decim=2, verbose=False)
print(f"✅ 时频分析完成,数据形状: {power.data.shape}")

# ---------- 5. 时频图 ----------
print("\n绘制时频图...")
fig = power.plot(picks='Cz', baseline=(-0.5, 0), mode='percent',
                 vmin=-50, vmax=50, title='Cz ERD/ERS', show=True)
plt.show(block=True)

# ---------- 6. Alpha ERD/ERS ----------
print("\n提取 Alpha ERD/ERS...")
alpha_freqs = (frequencies >= 8) & (frequencies <= 13)
alpha_power = power.data[:, alpha_freqs, :].mean(axis=1)

fig, ax = plt.subplots(figsize=(12, 6))
times = power.times
for idx, ch_name in enumerate(power.ch_names):
    baseline_idx = (times >= -0.5) & (times <= 0)
    baseline_mean = alpha_power[idx, baseline_idx].mean()
    erd_ers = (alpha_power[idx, :] - baseline_mean) / baseline_mean * 100
    ax.plot(times, erd_ers, label=ch_name, linewidth=1.5)

ax.axvline(x=0, color='red', linestyle='--', alpha=0.5)
ax.axhline(y=0, color='black', linestyle='-', alpha=0.3)
ax.set_xlabel('时间 (秒)'); ax.set_ylabel('ERD/ERS (%)')
ax.set_title('Alpha (8-13 Hz) ERD/ERS', fontsize=14)
ax.legend(); ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('day8_alpha_erd_ers.png', dpi=150)
plt.show(block=True)

# ---------- 7. 保存 ----------
power.save('day8_tfr_power.h5', overwrite=True)
print("\n✅ 时频分析结果已保存")

print("\n" + "="*60)
print("第8天学习完成!")
print("="*60)
print("\n🎯 明日预告:第9天 - 源定位基础")
相关推荐
小许同学记录成长6 小时前
gr-analog 模拟信号模块完整源码分析
python·算法·信号处理
MediaTea6 小时前
PyTorch:主要模块简介
人工智能·pytorch·python·深度学习·机器学习
技术小猪猪6 小时前
PromptOps:用Python构建生产级提示词工程体系
人工智能·python·ai·自动化·prompt
工业互联网专业6 小时前
国潮男装微博评论数据分析系统的设计与实现 _flask+spider
python·flask·毕业设计·源码·课程设计·spider
BUG研究员_7 小时前
python之数据分析-pandas部分
python·信息可视化·数据分析
覆东流7 小时前
Python变量与数值类型
开发语言·后端·python
Cthy_hy7 小时前
Python 算法竞赛:快速IO+字符串常用方法一站式整理
开发语言·python·算法
技术钱7 小时前
字符分割器组件的使用
android·python
码界筑梦坊7 小时前
146-基于Python的智能手表数据可视化分析系统
python·信息可视化·智能手表