AI算法工程师 | 03人工智能基础-Python科学计算和可视化(三)Pandas

Python 之 数据处理分析模块 Pandas

Pandas 是基于 Numpy 的一套数据分析工具,该工具是为了解决数据分析任务而创建的。

  • 数据模型繁多:Pandas 纳入了大量标准的数据模型,提供了高效地操作大型数据集所需的工具;
  • 导入数据方便:Pandas 可以从各种文件格式中导入数据,如:CSV、JSON、SQL、Excel 等;
  • 处理数据便捷:Pandas 是 Python 语言的一个扩展程序库,提供了许多快速便捷地处理数据的函数和方法。

小贴士

一、Pandas 开发环境搭建

说明

  • Pandas 是第三方程序库,在使用 Pandas 前需确保安装了 Pandas 库。
  • 如果使用的是 Anaconda Python 开发环境,那么 Pandas 已经被集成进 Anaconda,并不需要单独安装。(由于自己使用的是 Miniconda Python 开发环境,需要单独安装 Pandas )

测试与安装

若不清楚 Python 环境是否安装了 Pandas,可先测试

  • Windows电脑中按键 win + R 后输入“cmd” → 在 cmd 的命令窗口输入 python
  • 进入 python 环境中后,输入 import pandas 并回车 →
  • 若输入后提示模块没有找到“ModuleNotFoundError: No module named 'pandas'”,说明未安装 Pandas;若什么都没显示,则说明已安装。
  • 注:输入 exit() 可退出 python 环境。

cmd 中使用 pip 命令安装 Pandas:(注意该命令是在 cmd 中,而非 python 环境中)

# 安装命令1(不指定版本)
pip install pandas

# 安装命令2(指定下载源,这样下载得更快)
pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

安装完成后,可以测试一下 Pandas 是否安装成功。下面是导入 pandas 模块的语句(该语句是在 python 环境中输入),若不报错,说明 Pandas 已经安装成功了。

# 导入 pandas 模块,并起别名为 pd 
# 注意:每次使用 pandas 前均需写导入模块的语句
import pandas as pd  

# 扩:这是查看 pandas 库的版本号的命令
import pandas
pandas.__version__ # 查看版本号(命令中,version前后均分别有两个下划线)

图示
安装

二、Pandas 数据类型

Pandas 中两个重要的数据类型:SeriesDataFrame

  • Series:表示数据列表(一维)
  • DataFrame:表示二维数据集(二维)

1. Series 对象创建

Series 语法格式

pandas.Series( data, index, dtype, name, copy)
'''
参数说明:
· data :一组数据(ndarray 类型)
· index:数据索引标签(若不指定,默认从 0 开始)
· dtype:数据类型,默认会自己判断
· name :设置名称(默认为 False)
'''

示例1 - 使用列表创建

  • 使用列表创建 Series 对象
import pandas as pd # 导包
data = pd.Series([1,2,3,4,5]) # 返回一个序列
data

结果

Series 对象本质上是调用 numpy 创建了一个一维数组,之后在其身上赋予了一个索引,从而组成了一个 Series。即:Series 对象中有 ① numpy 数组、② index 索引。

因此,pandas 中有两个重要的属性 values(Series 对象的原始数据) 和 index(对应 Series 对象的索引对象)

  • Series 对象中两个重要的属性 values 和 index
data.values # 查看属性 values
data.index # 查看属性 index

结果

  • 若不想让索引从 0 开始,可以指定索引值(index 属性)
data = pd.Series([4,3,6,7,9],index=['one','two','three','four','five'])
data

结果

  • 也可使用 list 列表指定 index 属性
data = pd.Series([4,3,6,7,9],index=list('abcde'))
data

结果

示例2 - 使用字典创建

  • 使用字典创建 Series 对象
import pandas as pd # 导包

# 使用字典创建 Series 对象,默认将 key 作为 index 属性

population_dict={'bj':3000,'gz':1500,'sh':2800,'sz':1200} # 可传字典
population_series=pd.Series(population_dict)
population_series

结果

  • 用字典创建 Series 对象,可指定 index 属性值。若 key 不存在,则值为 NaN(代表空值)
# 如果存在取交集
sub_series=pd.Series(population_dict,index=['bj','sh']) 
sub_series
# 如果不存在则值为 NaN
sub_series=pd.Series(population_dict,index=['bj','xa'])
sub_series

结果

示例3 - 使用标量与 index 创建

  • 标量与 index 属性创建 Series 对象
import pandas as pd # 导包

data = pd.Series(6,index=[6,5,8,9,3])
data

结果

2. DataFrame 对象创建

关于 DataFrame

DataFrame 可以看成一个数据框(表格),有行与列。其中,每一列可以是不同的值类型,如:数值、布尔、字符串等。

图示 - 由 Series 组成的 DataFrame:
图示

DataFrame 语法格式:

pandas.DataFrame( data, index, columns, dtype, copy)
'''
参数说明:
· data   :一组数据(ndarray、series, map, lists, dict 等类型)
· index  :数据索引标签(相当于:行索引)
· columns:列索引(默认为 RangeIndex 0, 1, 2, …, n)
· dtype  :数据类型
· copy   :拷贝数据(默认为 False)
'''

示例1 - 使用 Series 及字典创建

  • 将两个 Series 对象作为字典的值,就可以创建一个 DataFrame 对象
import pandas as pd # 导包

# 字典
population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
area_dict={'beijing':300,'guangzhou':200,'shanghai':180}

# 创建 2 个 series
population_series=pd.Series(population_dict)
area_series=pd.Series(area_dict)

# 通过 DataFrame 创建数据框
citys=pd.DataFrame({'area':area_series,'population':population_series})
citys

结果

  • 查看 DataFrame 对象的 values、index 和 columns 属性
citys.index # 数据索引标签(相当于:行索引)
citys.values # 数据值
citys.columns # 列索引

结果

示例2 - 使用列表创建

  • 既然可以用列表创建 Series 对象,那是不是也可以使用列表创建 DataFrame 对象呢?
import pandas as pd # 导包

# 字典
population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
area_dict={'beijing':300,'guangzhou':200,'shanghai':180}

# 使用列表创建 DataFrame 对象
citys=pd.DataFrame([population_dict,area_dict]) # 直接把两个字典放在列表中
citys # 会将‘beijing’‘shanghai’ ‘guangzhou’作为表头(列索引)

结果

从结果中可以看到,使用列表创建的 DataFrame 对象,若未指定 index,则行索引默认从 0 开始。

  • 使用列表创建 DataFrame 对象,可通过指定 index 设置行索引
import pandas as pd # 导包

# 字典
population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
area_dict={'beijing':300,'guangzhou':200,'shanghai':180}

# 创建 DataFrame 对象,并设置行索引
citys=pd.DataFrame([population_dict,area_dict], index=['population','area']) # 指定索引号名称
citys

结果

  • 对于上方的代码而言,可通过指定 columns,实现取某列(或过滤)的效果
pd.DataFrame([population_dict,area_dict], 
             index=['population','area'],columns=['beijing','guangzhou']) # 指定 columns,设置列索引

结果

  • 创建 DataFrame 对象,并通过指定 columns 设置列索引
import pandas as pd # 导包

# 创建 1 个 series
population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
population_series=pd.Series(population_dict)

# 设置列索引
pd.DataFrame(population_series,columns=['population']) # 指定列名
# pd.DataFrame({'population':population_series}) # 与上一行的代码等价

结果

  • 使用列表创建 Dataframe 对象
import pandas as pd # 导包

pd.DataFrame([{'a':i,'b':i*2} for i in range(3)])
# pd.DataFrame([{'a':i,'b':i*2} for i in range(3)], index=['一','二','三']) # 指定行名称

结果

示例3 - 使用二维数组创建

  • 使用一个二维数组并指定 columns 和 index 创建 DataFrame 对象
import pandas as pd # 导包
import numpy as np

# 指明行名称、列名称
pd.DataFrame(np.random.randint(0, 100, (4,3)), index=['a','b','c','d'], columns=['a','b','c']) 

结果

示例4 - 使用字典创建

  • 创建一个数据集
import pandas as pd # 导包

pd.DataFrame({
    'Name':['zs','lisi','ww'],
    'Sno':['1001','1002','1003'],
    'Sex':['man','woman','man'],
    'Age':[17,18,19],
    'Score':[80,97,95]
})
data # 字典中所有的键都作为表头(列索引)

结果

  • 指定列索引
import pandas as pd # 导包

data = pd.DataFrame({
    'Name':['zs','lisi','ww'],
    'Sno':['1001','1002','1003'],
    'Sex':['man','woman','man'],
    'Age':[17,18,19],
    'Score':[80,97,95]
},columns=['Sno','Sex','Age','Score'])
data

结果

  • 指定行索引与列索引
import pandas as pd # 导包

data = pd.DataFrame({
    'Name':['zs','lisi','ww'],
    'Sno':['1001','1002','1003'],
    'Sex':['man','woman','man'],
    'Age':[17,18,19],
    'Score':[80,97,95]
},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
data

结果

小贴士:

3. 获取 Series 对象的值

示例

  • Series 对象的切片与索引
import pandas as pd # 导包

data = pd.Series([45,6,2,3,5],index=list('abcde'))
 
display('根据key获取:',data['a'])
display('切片获取:',data['a':'d']) # 注意,这里(标签索引)不是左闭右开,会取到 d
display('索引获取:',data[1]) # 取第二个
display('索引切片:',data[2:4])# 这里(位置索引)取值时,是左闭右开

结果

可以看到,Series 和 ndarray 数组类似,可以通过索引来访问元素。但 Series 对象的索引可分为位置索引和标签索引。

其中,标签索引进行切片时:左闭右闭;而位置索引:左闭右开。

  • 当 Series 对象的标签索引和位置索引存在相同时,无法区分是按哪种索引获取,怎么办?
data=pd.Series([5,6,7,8],index=[1,2,3,4])
data[1]  

结果

上方的 Series 对象 data 中,位置索引与标签索引有相同值 1,则 data[1] 代表的含义便不明确,此时需使用 loc(标签索引)、iloc(位置索引)。

  • 使用 Series 对象中 loc 与 iloc 获取值
data.loc[1] # 根据名字(标签索引)取值
data.iloc[1] # 根据位置索引取值

结果

4. 获取 DataFrame 的值

获取 DataFrame 的值的介绍

DataFrame 对象获取的数据:

  • 可传入具体的列名 —— 通过列名选择数据的方式叫做普通索引
  • 还可以传入具体列的位置( iloc 方法)—— 传入列的位置选择数据的方式叫做位置索引

其中,获取连续的某几列时,用普通索引和位置索引都可以做到。由于要获取的列是连续的,所以需要对列进行切片来获取数据。

获取的方式主要有两种:

  • 一种是普通索引,即传入具体行索引的名称,需要用到 loc 方法;
  • 另外一种是位置索引,即传入具体的行数,需要用到 iloc 方法。

示例1 - 获取列

  • 创建 DataFrame 对象
import pandas as pd # 导包
import numpy as np

data=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('ABCD'))
data

结果

  • 获取列:① 传入具体的列名
print('获取‘B’列:')
print(data['B']) # 如果要获取一列,则只需要传入一个列名
print('获取‘A’‘C’两列:')
print(data[['A','C']]) # 如果是同时选择多列,则传入多个列名(用一个 list 存放)即可

结果

  • 获取列:② 传入具体列的位置
print('获取第 1 列:')
print(data.iloc[:,0])
print('获取第 1 列和第 3 列:')
print(data.iloc[:,[0,2]])

# 说明:iloc 后的方括号中
# ① 逗号之前的部分表示要获取的行的位置。只输入一个冒号,不输入任何数值表示获取所有的行;
# ② 逗号之后的方括号表示要获取的列的位置,列的位置同样也是从 0 开始计数。

结果

  • 获取连续的几列(切片获取)
print('获取 A B 两列,使用位置索引获取:')
print(data.iloc[:,0:2])
print('获取 A B C 三列,使用普通索引获取:')
print(data.loc[:,'A':'C'])

结果

示例2 - 获取行

  • 获取某一行或某几行
print('获取 a 行,普通索引获取:')
print(data.loc['a'])
print('获取 a c 行,普通索引获取:')
print(data.loc[['a','c']])
print('获取第 1 行,位置索引获取:')
print(data.iloc[0])
print('获取第 1 行第 3 行,位置索引获取:')
print(data.iloc[[0,2]])

结果

  • 获取连续的几行(切片获取)
# 选择连续的某几行和选择连续某几列类似:把连续行的位置用一个区间表示

print('选择第 1 行 第 2 行,使用位置索引:')
print(data.iloc[0:2])
print('选择 a 行 b 行,使用普通索引:')
print(data.loc['a':'b'])

结果

示例3 - 同时获取行和列

  • 同时选择连续的部分行和部分列
print('同时获取 a b c 行,A B 列,使用普通索引:')
print(data.loc['a':'c','A':'B'] )
print('同时获取 a b 行,A B 列,使用位置索引:')
print(data.iloc[0:2,0:2])

结果

  • 同时选择不连续的部分行和部分列
print('同时获取 a c 行,ABD 列,使用普通索引:')
print(data.loc[['a','c'],['A','B','D']])
print('同时获取 a c 行,ABD 列,使用位置索引:')
print(data.iloc[[0,2],[0,1,3]])

结果

5. Series 的方法

Series 对象中有很多常用的方法可以对数据进行各种处理。例如:

方法描述
mean对某一列数据取平均数
min获取最小值
max获取最大值
std获取标准差

示例 - 对数据集进行各种运算,并排序

  • 创建一个数据集
import pandas as pd # 导包

data = pd.DataFrame({
    'Name':['zs','lisi','ww'],
    'Sno':['1001','1002','1003'],
    'Sex':['man','woman','man'],
    'Age':[17,18,19],
    'Score':[80,97,95]
},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
display('数据集',data)

结果

  • 计算平均值、最大值、最小值、标准差
ages = data['Age'] # 获取数据集中 Age 列的所有
print(ages)

ages.mean(), ages.min(), ages.max(), ages.std()

结果

  • 排序(正序)
ages.sort_values() # 对 Age 列进行排序(默认正序排序)

结果

  • 降序排序
ages.sort_values(ascending=False) #  对 Age 列进行降序排序

结果

6. Series 的条件过滤

Series 对象也可像 SQL 语句一样,通过指定条件进行数据的过滤。

示例

  • 筛选出成绩大于平均值的数据
import pandas as pd # 导包

# 创建数据集
data = pd.DataFrame({
    'Name':['zs','lisi','ww'],
    'Sno':['1001','1002','1003'],
    'Sex':['man','woman','man'],
    'Age':[17,18,19],
    'Score':[80,97,95]
},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
 
# 取出 'Score' 列的数据,并对数据进行筛选
scores = data['Score']
print(scores.mean()) # 平均值
scores[scores>scores.mean()] # 筛选出大于平均值的

结果

7. DataFrame 的条件过滤

DataFrame 与 Series 类似,也可使用条件进行过滤。

示例

  • 一个条件进行筛选:输出数据中所有成绩大于平均值的记录
import pandas as pd # 导包

# 创建数据集
data = pd.DataFrame({
    'Name':['zs','lisi','ww'],
    'Sno':['1001','1002','1003'],
    'Sex':['man','woman','man'],
    'Age':[17,18,19],
    'Score':[80,97,95]
},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
 
# 输出数据中所有成绩大于平均值的记录
scores = data['Score'] # 取出 'Score' 列的数据
print(scores.mean())
data[scores>scores.mean()] # data 中取值

结果

  • 多个条件进行筛选
# 且
ages = data['Age'] # 获取数据集中 Age 列的所有
data[(scores>scores.mean()) & (ages<19)] # 成绩大于平均值,且 年龄小于 19
# 或
data[(scores>scores.mean()) | (ages<19)] # 成绩大于平均值,或 年龄小于 19

结果

  • 根据条件进行筛选后,再通过 loc 取值
# 获取成绩大于平均值的所有记录,只显示 Sno Age Score 三列
data[scores>scores.mean()].loc[:,['Sno','Age','Score']] 

结果

三、处理缺失值

何谓缺失值?缺失值是指由某些原因导致部分数据为空。

对于为空的这部分数据,一般有两种处理方式:

  • 方式一:删除,即把含有缺失值的数据删除;
  • 方式二:填充,即把缺失的那部分数据用某个值代替。

1. 缺失值查看

在对缺失值进行处理前,需要把缺失值找出来,即查看哪列有缺失值。

Pandas 中缺失值用 NaN 表示,通过调用 info() 方法可看到返回的每一列的缺失情况。

示例

  • info() 方法查看缺失值
import pandas as pd # 导包
import numpy as np

df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
df.info() # 缺失值查看 

结果

  • isnull() 方法可判断哪个值是缺失值,若为缺失值则返回 True,否则返回 False
import pandas as pd # 导包
import numpy as np

data=pd.Series([3,4,np.nan,1,5,None])
print(data.isnull(),'\n') # isnull()方法判断是否是缺值
print(data[data.isnull()],'\n') # 获取缺值
print(data[data.notnull()]) # 获取非空值

结果

2. 缺失值删除

缺失值分为两种:

  • 一种是:一行中某个字段是缺失值;
  • 另一种是:一行中的字段全部为缺失值,即为一个空白行。

调用 dropna() 方法删除缺失值:

  • dropna() 方法默认删除含有缺失值的行,即只要某一行有缺失值就把这一行删除;
  • 如果想按列为单位删除缺失值,需要传入参数 axis=’columns’

示例

  • dropna() 方法删除缺失值
import pandas as pd # 导包
import numpy as np

df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]]) # 3行 3列

new_df = df.dropna() # 缺失值删除(默认为以行为单位剔除)
new_df

结果

  • 按列进行删除缺失值(传入参数 axis=’columns’)
df.dropna(axis='columns') # 以列为单位剔除

结果

  • 若想删除空白行,需给 dropna() 方法中传入参数 how=’all’ ,默认值为 any
df.dropna(how='all') # 某行中所有数据为 nan 时才剔除该行

结果

3. 缺失值填充

由于数据是宝贵的,一般情况下如果数据缺失比例不高,尽量不会选择删除,而是选择填充。

调用 fillna() 方法填充缺失值:

  • 在 fillna() 方法中输入要填充的值,可对数据表中的所有缺失值进行填充;
  • 还可以通过 method 参数使用前一个数和后一个数来进行填充。

示例

  • Series 对象缺失值填充
import pandas as pd # 导包
import numpy as np

data=pd.Series([3,4,np.nan,1,5,None])
print('以 0 进行填充:')
display(data.fillna(0))
print('以前一个数进行填充:')
display(data.fillna(method='ffill'))
print('以后一个数进行填充:')
display(data.fillna(method='bfill'))
print('先按后一个,再按前一个')
display(data.fillna(method='bfill').fillna(method='ffill')) 

结果

  • DataFrame 对象缺失值填充
import pandas as pd # 导包
import numpy as np

df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
print('使用数值 0 来填充:')
display(df.fillna(0))
print('使用行的前一个数来填充:')
display(df.fillna(method='ffill'))
print('使用列的后一个数来填充:')
display(df.fillna(method='bfill' ,axis=1)) 

结果

  • 使用列的平均值进行填充(常用)
import pandas as pd # 导包
import numpy as np

df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
display(df) # 原数据 df

for i in df.columns:
    df[i]=df[i].fillna(np.nanmean(df[i])) # 将填充完后的序列赋值给原序列(达到修改原数据的效果)
display(df) # 填充后的数据 df

结果

四、拼接

示例1 - Series 对象拼接

  • 使用 concat() 方法对 Series 对象进行拼接
import pandas as pd # 导包

ser1=pd.Series([1,2,3],index=list('ABC'))
ser2=pd.Series([4,5,6],index=list('DEF'))
pd.concat([ser1,ser2])

结果

示例2 - DataFrame 对象拼接

  • 多个 df 对象拼接,默认找相同的列索引进行合并
import pandas as pd # 导包

# 声明一个函数
def make_df(cols,index):
    data={c:[str(c)+str(i) for i in index] for c in cols}
    return pd.DataFrame(data,index=index)
    
# 调用函数,创建两个 DataFrame 对象
df1=make_df('AB',[1,2])
df2=make_df('AB',[3,4])

# 拼接(默认找相同的列索引进行合并)
pd.concat([df1, df2]) 

结果

  • 添加 axis 参数,可按列拼接
pd.concat([df1, df2], axis=1) # 按列拼接,axis=1与 axis='columns' 等价

结果

从上图结果中可以看到,多个 df 对象按列拼接时,若行索引不同,行也会往下拼接,并用 NaN 填充没有的数据。

多个 df 对象拼接,当设置 axis=1 按列拼接时,相同的行索引会进行合并,如:

结果

示例3 - DataFrame 对象拼接的索引重复问题

  • 多个 df 对象拼接,索引(行索引)重复问题
import pandas as pd # 导包

# 声明一个函数
def make_df(cols,index):
    data={c:[str(c)+str(i) for i in index] for c in cols}
    return pd.DataFrame(data,index=index)
    
# 调用函数,创建两个 DataFrame 对象
df1=make_df('AB',[1,2])
df2=make_df('AB',[1,2])

# 拼接(默认找相同的列索引进行合并)
pd.concat([df1, df2]) 

结果

  • 上方的行索引有重复,若想让结果的索引重新排放,可加 ignore_index 属性
# 解决索引重复问题,方式 1 :加 ignore_index 属性
pd.concat([df1,df2], ignore_index=True) 

结果

  • 还可通过加 keys 属性,解决索引重复问题
# 解决索引重复问题,方式 2 :加 keys 属性
pd.concat([df1,df2],keys=['df1', 'df2'])

结果

示例4 - join 拼接

  • 两个 df 对象拼接,join 内连接做交集
import pandas as pd # 导包

# 声明一个函数
def make_df(cols,index):
    data={c:[str(c)+str(i) for i in index] for c in cols}
    return pd.DataFrame(data,index=index)
    
# 调用函数,创建两个 DataFrame 对象
a=make_df('ABC',[1,2])
b=make_df('BCD',[3,4])

# 内连接(取列相交部分)
pd.concat([a,b],join='inner')

结果

五、merge 的使用

pandas 中 的 merge 和 concat 类似,但主要是用于两组有 key column 的数据,统一索引的数据。通常也被用在 Database 的处理当中。

使用 merge 合并时有 4 种方式 how = [‘left’, ‘right’, ‘outer’, ‘inner’],默认为 inner。

示例 - merge 的使用

  • 默认以 how=’inner’ 进行合并
import pandas as pd # 导包

# 创建 DataFrame 对象
left=pd.DataFrame({'key':['k0','k1','k2','k3'],
                   'A':['A0','A1','A2','A3'],
                   'B':['B0','B1','B2','B3'],
                 }) # 通过字典方式传入3个列

right=pd.DataFrame({'key':['k0','k1','k4','k3'],
                   'C':['C0','C1','C2','C3'],
                   'D':['D0','D1','D2','D3'],
                 }) 

# 合并
pd.merge(left, right) # 默认合并,此处以 'key' 作为公共部分(可能会丢数据)

# 语句说明:
# 先看left、right这两内容 是否有相同名字这一列,
# 对相同列 key 的数据做交集,再把交集所对应的其他列数据合并到结果中去                 

结果

  • 参数 how=’outer’ 进行合并
pd.merge(left, right, how='outer') # 数据全部保留

结果

  • 参数 how=’left’ 进行合并
pd.merge(left, right, how='left') # 左侧的全部保留

结果

  • 参数 how=’right’ 进行合并
pd.merge(left, right, how='right')# 右侧的全部保留

结果


—— 说明:本文写于 7.30~8.1,文中内容基于 python3,使用工具 Jupyter Notebook 编写的代码
(本文中使用函数前的 np 代表 Numpy 的别名,pd 为 Pandas 的别名,每次使用前需导入相关模块)

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值