Python大数据实战(八):SVM回归+极区图——气象数据分析与可视化全流程实战

Python大数据实战(八):SVM回归+极区图——气象数据分析与可视化全流程实战



前言

“靠海的城市是不是更凉快?”

每到夏天,这个问题总会浮现在脑海。住在内陆城市的人羡慕海边的凉爽,而海边的人却说"也没差多少"。那么,海洋到底对气候有多大影响?这个看似感性的问题,其实可以用数据科学给出一个理性的答案。

本文将以意大利波河流域的 10 个城市为研究对象,使用 Python 对气象数据(温度、湿度、风向、风速)进行全面的分析与可视化。我们将使用 matplotlib 绘制多种图表,使用 scikit-learn 的 SVR(支持向量回归) 对温度与离海距离的关系进行建模,并使用 极区图(玫瑰图) 展示风向分布。全文超过 6000 字,包含完整可运行代码和详细踩坑记录。


一、项目全景概览

1.1 项目目标

阶段任务技术栈
数据加载读取 10 个城市的气象 CSV 数据Pandas
温度分析分析气温日变化趋势、最高/最低温与离海距离关系Matplotlib
回归建模使用 SVR 拟合温度-距离关系,找到海洋影响分界点Scikit-learn SVR
湿度分析分析近海/内陆城市湿度差异Matplotlib
风向分析绘制风向频率玫瑰图(极区图)Matplotlib + NumPy
风速分析计算各方向平均风速并可视化自定义函数

1.2 技术路线架构图

10个城市气象CSV数据

Pandas数据加载

温度数据

湿度数据

风向/风速数据

温度分析模块

单城市日变化曲线

近海vs内陆对比图

最高温-距离散点图

最低温-距离散点图

SVR回归建模

近海组线性拟合

内陆组线性拟合

fsolve求交点

海洋影响分界距离

湿度分析模块

近海vs内陆湿度曲线

最大湿度-距离关系

最小湿度-距离关系

风向分析模块

np.histogram分面元

showRoseWind极区图

RoseWind_Speed风速玫瑰图

1.3 前置知识要求

知识领域具体要求重要程度
Python基础列表推导式、函数定义、NumPy数组操作⭐⭐⭐⭐⭐
PandasDataFrame读取、列筛选、统计函数(max/min/mean)⭐⭐⭐⭐
Matplotlibsubplot、plot、极坐标绘图⭐⭐⭐⭐
Scikit-learnSVR回归器的基本使用⭐⭐⭐
数学基础线性回归、直线方程、交点求解⭐⭐⭐

二、研究背景与数据准备

2.1 研究问题定义

我们要回答的核心问题是:海洋对一个地区的气候(温度、湿度)有多大影响?影响范围是多少公里?

为了控制变量,我们选择了意大利波河流域——这是一片从亚得里亚海向内陆延伸数百公里的平原,排除了山地海拔因素的干扰。

2.2 样本城市选择

选取 10 个城市作为研究样本,按离海距离分为两组:

分组城市离海距离
近海组(<100km)Ravenna(拉文纳)最近
Cesena(切塞纳)
Faenza(法恩莎)
Ferrara(费拉拉)
Bologna(博洛尼亚)
内陆组(100-400km)Mantova(曼托瓦)
Piacenza(皮亚琴察)
Milano(米兰)
Asti(阿斯蒂)
Torino(都灵)最远

2.3 数据加载

每个城市的气象数据以 CSV 格式存储,包含日期时间、温度、湿度、风速、风向等字段。

import numpy as np
import pandas as pd
import datetime

# 加载10个城市的气象数据
df_ferrara = pd.read_csv('WeatherData/ferrara_270615.csv')
df_milano = pd.read_csv('WeatherData/milano_270615.csv')
df_mantova = pd.read_csv('WeatherData/mantova_270615.csv')
df_ravenna = pd.read_csv('WeatherData/ravenna_270615.csv')
df_torino = pd.read_csv('WeatherData/torino_270615.csv')
df_asti = pd.read_csv('WeatherData/asti_270615.csv')
df_bologna = pd.read_csv('WeatherData/bologna_270615.csv')
df_piacenza = pd.read_csv('WeatherData/piacenza_270615.csv')
df_cesena = pd.read_csv('WeatherData/cesena_270615.csv')
df_faenza = pd.read_csv('WeatherData/faenza_270615.csv')

# 查看数据结构
print(df_ravenna.head())
print(f"数据形状: {df_ravenna.shape}")

三、温度数据分析

3.1 单城市气温日变化

首先以米兰为例,分析一天中气温的变化趋势。

%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser

# 提取温度和日期数据
y1 = df_milano['temp']       # 温度列
x1 = df_milano['day']        # 日期时间列

# 将字符串日期转换为 datetime 对象
day_milano = [parser.parse(x) for x in x1]

# 创建画布和坐标轴
fig, ax = plt.subplots()

# 调整 x 轴刻度旋转角度,方便查看
plt.xticks(rotation=70)

# 设置时间显示格式为 时:分
hours = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(hours)

# 绘制红色折线图
ax.plot(day_milano, y1, 'r')
plt.title('米兰一天气温变化趋势')
plt.xlabel('时间')
plt.ylabel('温度 (℃)')
plt.show()

观察结论:气温走势接近正弦曲线——早上开始逐渐升高,最高温出现在下午 2-6 点,随后逐渐下降,凌晨 6 点达到最低值。

3.2 近海 vs 内陆城市温度对比

为了验证"海洋影响气温"的假设,我们同时绘制 3 个近海城市和 3 个内陆城市的气温曲线。

# 近海城市(红色)
y1, x1 = df_ravenna['temp'], df_ravenna['day']
y2, x2 = df_faenza['temp'], df_faenza['day']
y3, x3 = df_cesena['temp'], df_cesena['day']

# 内陆城市(绿色)
y4, x4 = df_milano['temp'], df_milano['day']
y5, x5 = df_asti['temp'], df_asti['day']
y6, x6 = df_torino['temp'], df_torino['day']

# 日期转换
day_ravenna = [parser.parse(x) for x in x1]
day_faenza = [parser.parse(x) for x in x2]
day_cesena = [parser.parse(x) for x in x3]
day_milano = [parser.parse(x) for x in x4]
day_asti = [parser.parse(x) for x in x5]
day_torino = [parser.parse(x) for x in x6]

# 绘制对比图
fig, ax = plt.subplots()
plt.xticks(rotation=70)
hours = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(hours)

# 近海组用红色,内陆组用绿色
ax.plot(day_ravenna, y1, 'r', day_faenza, y2, 'r', day_cesena, y3, 'r')
ax.plot(day_milano, y4, 'g', day_asti, y5, 'g', day_torino, y6, 'g')

plt.title('近海城市(红) vs 内陆城市(绿) 气温对比')
plt.legend(['近海城市', '内陆城市'])
plt.show()

关键发现:近海城市(红色)的最高气温明显低于内陆城市(绿色),但最低气温差异不大。这说明海洋对白天最高温的"降温"效果更显著。

3.3 最高温/最低温与离海距离的关系

接下来,我们收集 10 个城市的最高温和最低温,绘制它们与离海距离的散点图。

# 各城市离海距离(km)
dist = [
    df_ravenna['dist'][0], df_cesena['dist'][0], df_faenza['dist'][0],
    df_ferrara['dist'][0], df_bologna['dist'][0], df_mantova['dist'][0],
    df_piacenza['dist'][0], df_milano['dist'][0], df_asti['dist'][0],
    df_torino['dist'][0]
]

# 各城市最高温度
temp_max = [
    df_ravenna['temp'].max(), df_cesena['temp'].max(), df_faenza['temp'].max(),
    df_ferrara['temp'].max(), df_bologna['temp'].max(), df_mantova['temp'].max(),
    df_piacenza['temp'].max(), df_milano['temp'].max(), df_asti['temp'].max(),
    df_torino['temp'].max()
]

# 各城市最低温度
temp_min = [
    df_ravenna['temp'].min(), df_cesena['temp'].min(), df_faenza['temp'].min(),
    df_ferrara['temp'].min(), df_bologna['temp'].min(), df_mantova['temp'].min(),
    df_piacenza['temp'].min(), df_milano['temp'].min(), df_asti['temp'].min(),
    df_torino['temp'].min()
]

# 绘制最高温-距离散点图
fig, ax = plt.subplots()
ax.plot(dist, temp_max, 'ro')  # 红色圆点
plt.title('最高温度与离海距离的关系')
plt.xlabel('离海距离 (km)')
plt.ylabel('最高温度 (℃)')
plt.show()

# 绘制最低温-距离散点图
plt.axis((0, 400, 15, 25))
plt.plot(dist, temp_min, 'bo')  # 蓝色圆点
plt.title('最低温度与离海距离的关系')
plt.xlabel('离海距离 (km)')
plt.ylabel('最低温度 (℃)')
plt.show()

关键发现

  • 最高温随离海距离增加而升高,但在 60-70km 后趋于平缓
  • 最低温与离海距离无明显关系——海洋对夜间低温的影响不显著

四、SVR回归建模——量化海洋影响

4.1 SVR 方法简介

SVR(Support Vector Regression,支持向量回归)是 SVM 在回归问题上的扩展。与普通线性回归不同,SVR 允许一定范围内的误差,通过核函数可以处理非线性关系。这里我们使用线性核kernel='linear')来拟合温度-距离关系。

4.2 分组拟合与交点求解

将 10 个城市分为近海组(前 5 个)和内陆组(后 5 个),分别用 SVR 拟合两条直线,然后求交点——这个交点就是海洋影响的分界距离。

from sklearn.svm import SVR
from scipy.optimize import fsolve

# 分组
dist1 = dist[0:5]   # 近海组距离
dist2 = dist[5:10]  # 内陆组距离

# 将列表转为 SVR 需要的二维数组格式
dist1 = [[x] for x in dist1]
dist2 = [[x] for x in dist2]

temp_max1 = temp_max[0:5]   # 近海组最高温
temp_max2 = temp_max[5:10]  # 内陆组最高温

# 创建 SVR 模型(线性核,C=1000 尽量拟合数据)
svr_lin1 = SVR(kernel='linear', C=1e3)
svr_lin2 = SVR(kernel='linear', C=1e3)

# 拟合数据(这一步可能较慢,耐心等待)
svr_lin1.fit(dist1, temp_max1)
svr_lin2.fit(dist2, temp_max2)

# 生成预测用的 x 值
xp1 = np.arange(10, 100, 10).reshape((9, 1))
xp2 = np.arange(50, 400, 50).reshape((7, 1))

# 预测 y 值
yp1 = svr_lin1.predict(xp1)
yp2 = svr_lin2.predict(xp2)

# 绘制拟合结果
fig, ax = plt.subplots()
ax.set_xlim(0, 400)
ax.plot(xp1, yp1, c='b', label='Strong sea effect')   # 近海趋势
ax.plot(xp2, yp2, c='g', label='Light sea effect')    # 内陆趋势
ax.plot(dist, temp_max, 'ro')                          # 原始数据点
plt.legend()
plt.title('SVR 拟合:温度-距离关系')
plt.xlabel('离海距离 (km)')
plt.ylabel('最高温度 (℃)')
plt.show()

# 输出斜率和截距
print(f"近海组斜率: {svr_lin1.coef_[0][0]:.4f}, 截距: {svr_lin1.intercept_[0]:.4f}")
print(f"内陆组斜率: {svr_lin2.coef_[0][0]:.4f}, 截距: {svr_lin2.intercept_[0]:.4f}")

# 求两条直线的交点
def line1(x):
    """近海组拟合直线"""
    a1 = svr_lin1.coef_[0][0]
    b1 = svr_lin1.intercept_[0]
    return a1 * x + b1

def line2(x):
    """内陆组拟合直线"""
    a2 = svr_lin2.coef_[0][0]
    b2 = svr_lin2.intercept_[0]
    return a2 * x + b2

def findIntersection(fun1, fun2, x0):
    """使用 fsolve 求解两函数交点"""
    return fsolve(lambda x: fun1(x) - fun2(x), x0)

result = findIntersection(line1, line2, 0.0)
print(f"交点坐标: [x, y] = [{result[0]:.0f}, {line1(result)[0]:.0f}]")

# 可视化交点
x = np.linspace(0, 300, 31)
plt.plot(x, line1(x), x, line2(x), result, line1(result), 'ro')
plt.title('两条拟合直线的交点')
plt.xlabel('离海距离 (km)')
plt.ylabel('最高温度 (℃)')
plt.show()

结论:两条直线的交点约为 [53, 30],意味着在离海约 53 公里处是海洋影响气温的分界点。53 公里以内,气温随距离快速上升(从 28℃ 到 31℃);53 公里以外,气温增速明显放缓。


五、湿度数据分析

5.1 近海 vs 内陆湿度日变化

# 读取湿度数据
y1, x1 = df_ravenna['humidity'], df_ravenna['day']
y2, x2 = df_faenza['humidity'], df_faenza['day']
y3, x3 = df_cesena['humidity'], df_cesena['day']
y4, x4 = df_milano['humidity'], df_milano['day']
y5, x5 = df_asti['humidity'], df_asti['day']
y6, x6 = df_torino['humidity'], df_torino['day']

# 日期转换
day_ravenna = [parser.parse(x) for x in x1]
day_faenza = [parser.parse(x) for x in x2]
day_cesena = [parser.parse(x) for x in x3]
day_milano = [parser.parse(x) for x in x4]
day_asti = [parser.parse(x) for x in x5]
day_torino = [parser.parse(x) for x in x6]

# 绘制湿度对比图
fig, ax = plt.subplots()
plt.xticks(rotation=70)
hours = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(hours)

# 近海红色,内陆绿色
ax.plot(day_ravenna, y1, 'r', day_faenza, y2, 'r', day_cesena, y3, 'r')
ax.plot(day_milano, y4, 'g', day_asti, y5, 'g', day_torino, y6, 'g')
plt.title('近海城市(红) vs 内陆城市(绿) 湿度对比')
plt.xlabel('时间')
plt.ylabel('湿度 (%)')
plt.show()

5.2 湿度极值与距离关系

# 收集各城市最大湿度和最小湿度
hum_max = [
    df_ravenna['humidity'].max(), df_cesena['humidity'].max(),
    df_faenza['humidity'].max(), df_ferrara['humidity'].max(),
    df_bologna['humidity'].max(), df_mantova['humidity'].max(),
    df_piacenza['humidity'].max(), df_milano['humidity'].max(),
    df_asti['humidity'].max(), df_torino['humidity'].max()
]

hum_min = [
    df_ravenna['humidity'].min(), df_cesena['humidity'].min(),
    df_faenza['humidity'].min(), df_ferrara['humidity'].min(),
    df_bologna['humidity'].min(), df_mantova['humidity'].min(),
    df_piacenza['humidity'].min(), df_milano['humidity'].min(),
    df_asti['humidity'].min(), df_torino['humidity'].min()
]

# 绘制最大湿度-距离关系
plt.plot(dist, hum_max, 'bo')
plt.title('最大湿度与离海距离的关系')
plt.xlabel('离海距离 (km)')
plt.ylabel('最大湿度 (%)')
plt.show()

# 绘制最小湿度-距离关系
plt.plot(dist, hum_min, 'bo')
plt.title('最小湿度与离海距离的关系')
plt.xlabel('离海距离 (km)')
plt.ylabel('最小湿度 (%)')
plt.show()

关键发现

  • 近海城市的湿度普遍高于内陆城市(全天差距约 20%)
  • 但湿度和距离之间不存在明显的线性关系——10 个数据点太少,不足以描述趋势

六、风向频率玫瑰图(极区图)

6.1 为什么用极区图?

风向数据是 0°~360° 的角度值,用普通笛卡尔坐标系散点图展示效果很差——数据点散落在整个圆上,难以看出分布规律。极区图(Polar Chart) 是展示角度分布数据的最佳选择。

6.2 构建风向直方图

# 将 360° 分为 8 个面元,每个 45°
hist, bins = np.histogram(df_ravenna['wind_deg'], 8, [0, 360])
print("各面元风向频次:", hist)
print("面元边界:", bins)
# 输出示例: hist = [0, 5, 11, 1, 0, 1, 0, 0]
#          bins = [0, 45, 90, 135, 180, 225, 270, 315, 360]

6.3 封装极区图绘制函数

def showRoseWind(values, city_name, max_value):
    """
    绘制风向频率玫瑰图(极区图)
    
    参数:
        values: 各面元的风向频次数组(长度=8)
        city_name: 城市名称(用于标题)
        max_value: 最大频次值(用于颜色映射)
    """
    N = 8  # 8个扇区
    
    # 计算每个扇区的角度位置(弧度制)
    # theta = [π/8, 3π/8, 5π/8, ..., 15π/8]
    theta = np.arange(2 * np.pi / 16, 2 * np.pi, 2 * np.pi / 8)
    radii = np.array(values)
    
    # 创建极坐标系
    plt.axes([0.025, 0.025, 0.95, 0.95], polar=True)
    
    # 颜色映射:值越大颜色越接近蓝色
    colors = [(1 - x / max_value, 1 - x / max_value, 0.75) for x in radii]
    
    # 绘制柱状图(极坐标)
    plt.bar(theta, radii, width=(2 * np.pi / N), bottom=0.0, color=colors)
    
    # 设置标题
    plt.title(city_name, x=0.2, fontsize=20)

# 绘制 Ravenna 的风向玫瑰图
showRoseWind(hist, 'Ravenna', max(hist))
plt.show()

解读:Ravenna 当天大部分时间风向为西南和正西方向(对应面元频次最高)。

6.4 风速均值玫瑰图

除了风向频次,我们还可以展示各方向的平均风速

def RoseWind_Speed(df_city):
    """
    计算 8 个方向面元的平均风速
    
    参数:
        df_city: 某个城市的 DataFrame
    
    返回:
        各方向平均风速的 NumPy 数组(长度=8)
    """
    degs = np.arange(45, 361, 45)  # [45, 90, 135, ..., 360]
    tmp = []
    for deg in degs:
        # 筛选风向在 (deg-46, deg) 范围内的数据,计算平均风速
        avg_speed = df_city[
            (df_city['wind_deg'] > (deg - 46)) & 
            (df_city['wind_deg'] < deg)
        ]['wind_speed'].mean()
        tmp.append(avg_speed)
    return np.array(tmp)

# 绘制 Ravenna 的风速玫瑰图
showRoseWind(RoseWind_Speed(df_ravenna), 'Ravenna - Wind Speed', max(hist))
plt.show()

# 对比 Ferrara 的风向分布
hist_ferrara, _ = np.histogram(df_ferrara['wind_deg'], 8, [0, 360])
showRoseWind(hist_ferrara, 'Ferrara', max(hist_ferrara))
plt.show()

七、常见错误与解决方案

错误案例 1:SVR.fit() 报错 “Expected 2D array, got 1D array”

现象

ValueError: Expected 2D array, got 1D array instead:
array=[...]
Reshape your data either using array.reshape(-1, 1)

原因:scikit-learn 要求特征矩阵必须是二维数组(n_samples × n_features),而直接传入列表会被当作一维数组。

解决方案

# ❌ 错误写法
dist1 = [10, 20, 30, 40, 50]
svr_lin1.fit(dist1, temp_max1)  # 报错!

# ✅ 正确写法:将列表转为二维数组
dist1 = [[x] for x in dist1]  # 列表推导式
# 或者使用 NumPy
dist1 = np.array(dist1).reshape(-1, 1)
svr_lin1.fit(dist1, temp_max1)  # 正常运行

错误案例 2:极区图中文标题显示为方框

现象:极区图标题中的中文显示为 □□□。

原因:matplotlib 默认字体不支持中文。

解决方案

import matplotlib.pyplot as plt

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans', 'WenQuanYi Micro Hei']
# 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False

# 如果仍不生效,可以指定字体路径
from matplotlib.font_manager import FontProperties
font = FontProperties(fname='/usr/share/fonts/truetype/wqy/wqy-microhei.ttc')
plt.title('拉文纳风向玫瑰图', fontproperties=font)

错误案例 3:fsolve 不收敛或返回错误交点

现象fsolve 返回的结果与预期不符,或报错 “The iteration is not making good progress”。

原因:初始猜测值 x0 离真实交点太远,导致迭代不收敛。

解决方案

from scipy.optimize import fsolve

def findIntersection(fun1, fun2, x0):
    return fsolve(lambda x: fun1(x) - fun2(x), x0)

# ❌ 不好的初始值
result = findIntersection(line1, line2, 0.0)   # 如果真实交点在 200 附近,可能不收敛

# ✅ 根据散点图观察,给出合理的初始猜测
# 观察温度-距离散点图,两条趋势线的交点大约在 50-60km 之间
result = findIntersection(line1, line2, 50.0)  # 更好的初始值

# ✅ 更稳健的做法:尝试多个初始值
for x0 in [10, 50, 100, 200]:
    try:
        result = findIntersection(line1, line2, x0)
        print(f"x0={x0}: 交点={result[0]:.1f}")
    except Exception as e:
        print(f"x0={x0}: 失败 - {e}")

错误案例 4:np.histogram 面元边界设置不当

现象:风向数据无法正确分配到各个面元,某些面元频次始终为 0。

原因np.histogrambins 参数如果设置不当,边界值可能无法覆盖所有数据点。

解决方案

# ❌ 可能遗漏边界数据
hist, bins = np.histogram(df['wind_deg'], 8, [0, 360])
# 360° 的数据可能被遗漏(因为区间是左闭右开 [0, 360))

# ✅ 方案1:将范围设为 [0, 361)
hist, bins = np.histogram(df['wind_deg'], 8, [0, 361])

# ✅ 方案2:将 360° 的数据合并到 0° 面元
df['wind_deg'] = df['wind_deg'].apply(lambda x: 0 if x == 360 else x)
hist, bins = np.histogram(df['wind_deg'], 8, [0, 360])

八、实验总结与展望

8.1 核心结论

分析维度关键发现
温度-距离最高温随离海距离增加而升高,SVR 拟合交点约 53km 为海洋影响分界
最低温与离海距离无明显关系,海洋对夜间低温影响不显著
湿度近海城市湿度高于内陆约 20%,但无明确线性关系
风向极区图清晰展示风向分布,Ravenna 当天以西南/西风为主

8.2 项目亮点

  1. 科学假设驱动:从"海洋影响气候"的感性认知出发,用数据验证假设
  2. 多维度分析:覆盖温度、湿度、风向、风速四个维度
  3. SVR 回归量化:不仅定性分析,还通过回归建模找到具体的分界距离
  4. 极区图可视化:针对角度数据选择了最合适的可视化方式

8.3 改进方向

  • 时间维度扩展:本文仅分析了一天的数据,可以扩展到多日/多季节
  • 更多城市样本:10 个城市的数据点偏少,增加样本可提高统计显著性
  • 引入更多特征:加入气压、降雨量等气象指标进行多变量分析
  • 非线性模型:尝试 RBF 核的 SVR 或其他非线性回归方法

参考链接

  1. 图灵教育《Python 数据分析实战》第 2 章 — 本文核心参考来源
  2. scikit-learn SVR 官方文档 — SVR 参数详解
  3. Matplotlib 极坐标绘图指南 — 极区图官方教程
  4. SciPy fsolve 使用文档 — 方程组求解方法
  5. OpenWeatherMap API — 全球气象数据获取

下一篇预告

下一篇我们将进入金融风控领域,带来 《Python大数据实战(九):申请评分卡——银行信贷风控模型全流程实战》。我们将学习:

  • WOE 与 IV 值计算与特征筛选
  • 分箱(Binning)技术详解
  • 逻辑回归构建评分卡
  • KS 值与 AUC 评估模型效果
  • 评分刻度转换(Scorecard Scaling)

敬请期待!🚀

如果本文对你有帮助,欢迎点赞、收藏、关注三连!你的支持是我持续创作的动力 💪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hhzz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值