【中篇】NumPy简介


1 迭代数组

【1 迭代数组】一整节介绍nditer。

NumPy迭代器对象numpy.nditer提供了一种灵活访问一个或者多个数组元素的方式,该迭代器最基本的任务是完成对数组元素的访问。下面用arange()函数创建一个2×3数组,并使用nditer对它进行迭代。

import numpy as np

a=np.arange(6).reshape(2,3)
print('原始数组:')
print(a)
print('-----')

print('迭代输出元素:')
for x in np.nditer(a):
    print(x,end=',')

输出:

原始数组:
[[0 1 2]
 [3 4 5]]
-----
迭代输出元素:
0,1,2,3,4,5,

以上实例不是使用标准C或者Fortran顺序,选择的顺序是和数组内存布局一致的,这样做是为了提升访问的效率,默认是行序优先(row-major order,或者说是C-order),这反映了默认情况下只需访问每个元素,而无需考虑其特定顺序。可以通过迭代上述数组的转置来看到这一点,并与以C顺序访问数组转置的copy方式做对比,如下实例:

import numpy as np

a=np.arange(6).reshape(2,3)
print('原始数组:')
print(a)
print('-----')

print('迭代输出元素:')
for x in np.nditer(a.T):
    print(x,end=',')

print('\n-----')
for x in np.nditer(a.T.copy(order='C')):
    print(x,end=',')

输出:

原始数组:
[[0 1 2]
 [3 4 5]]
-----
迭代输出元素:
0,1,2,3,4,5,
-----
0,3,1,4,2,5,

可以看出,a和a.T的遍历顺序是一样的,也就是他们在内存中的存储顺序也是一样的,但是a.T.copy(order=‘C’)的遍历结果是不同的,那是因为它和前两种的存储方式是不一样的,默认是按行访问。

1.1 控制遍历顺序

1、for x in np.nditer(a, order=‘F’)——Fortran order,即是列序优先;

2、for x in np.nditer(a.T, order=‘C’)——C order,即是行序优先;

import numpy as np

a=np.arange(0,60,5).reshape(3,4)
print('原始数组:')
print(a)

print('-----')
b=a.T
print('原始数组的转置是:')
print(b)

print('-----')
c=b.copy(order='C')
print('以C风格顺序排序')
print(c)
for x in np.nditer(c):
    print(x,end=',')

print('\n-----')
c=b.copy(order='F')
print('以F风格顺序排序')
print(c)
for x in np.nditer(c):
    print(x,end=',')

输出:

原始数组:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]
-----
原始数组的转置是:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
-----
以C风格顺序排序
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
0,20,40,5,25,45,10,30,50,15,35,55,
-----
以F风格顺序排序
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
0,5,10,15,20,25,30,35,40,45,50,55,

以上输出我比较疑惑的是:以C风格顺序排序与以F风格顺序排序后输出数组居然一模一样,然后使用nditer后确实不一样…

可以通过显式设置,来强制nditer对象使用某种顺序:

import numpy as np

a=np.arange(0,60,5).reshape(3,4)
print('原始数组:')
print(a)

print('-----')
print('以C风格顺序排序')
for x in np.nditer(a,order='C'):
    print(x,end=',')

print('\n-----')
print('以F风格顺序排序')
for x in np.nditer(a,order='F'):
    print(x,end=',')

输出:

原始数组:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]
-----
以C风格顺序排序
0,5,10,15,20,25,30,35,40,45,50,55,
-----
以F风格顺序排序
0,20,40,5,25,45,10,30,50,15,35,55,

1.2 修改数组中元素的值

nditer对象有一个可选参数op_flags。默认情况下,nditer将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值的修改,必须指定op_flags为read-write或者write-only。

import numpy as np

a=np.arange(0,60,5).reshape(3,4)
print('原始数组:')
print(a)

print('-----')
for x in np.nditer(a,op_flags=['readwrite']):
    x[...]=2*x
print('修改后的数组是:')
print(a)

输出:

原始数组:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]
-----
修改后的数组是:
[[  0  10  20  30]
 [ 40  50  60  70]
 [ 80  90 100 110]]

1.3 使用外部循环

nditer类的构造器拥有flags参数,它可以接受下列值:

参数描述
c_index可以跟踪C顺序的索引
f_index可以跟踪Fortran顺序的索引
multi-index每次迭代可以跟踪一种索引类型
external_loop给出的值是具有多个值的一维数组,而不是零维数组

在下面的实例中,迭代器遍历对应于每列,并组合为一维数组。

import numpy as np

a=np.arange(0,60,5).reshape(3,4)
print('原始数组:')
print(a)

print('-----')
print('修改后的数组是:')
for x in np.nditer(a,flags=['external_loop'],order='F'):
    print(x,end=',')

输出:

原始数组:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]
-----
修改后的数组是:
[ 0 20 40],[ 5 25 45],[10 30 50],[15 35 55],

1.4 广播迭代

如果两个数组是可广播的,nditer组合对象能够同时迭代它们。假设数组a的维度为3×4,数组b的维度为1×4,则使用以下迭代器(数组b被广播到a的大小)。

import numpy as np

a=np.arange(0,60,5).reshape(3,4)
print('第一个数组:')
print(a)
b=np.array([1,2,3,4],dtype=int)
print('第二个数组:')
print(b)

print('-----')
print('修改后的数组是:')
for x,y in np.nditer([a,b]):
    print("%d:%d" % (x,y),end=',')

输出:

第一个数组:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]
第二个数组:
[1 2 3 4]
-----
修改后的数组是:
0:1,5:2,10:3,15:4,20:1,25:2,30:3,35:4,40:1,45:2,50:3,55:4,

2 数组操作

Numpy中包含了一些函数用于处理数组,大概可分为以下6类:

2.1 修改数组形状

函数描述
reshape不改变数据的条件下修改形状
flat数组元素迭代器
flatten返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
ravel返回展开数组

下面详细介绍这四个函数。

numpy.reshape函数可以在不改变数据的条件下修改形状,格式如下:

numpy.reshape(arr,newshape,order='C')

1、arr:要修改形状的数组

2、newshape:整数或者整数数组,新的形状应当兼容原有形状

3、order:‘C’–按行,‘F’–按列,‘A’–原顺序,‘k’–元素在内存中的出现顺序。

import numpy as np 
a = np.arange(0,60,5) 
print ('原始数组是:')
print (a)
print ('\n')
print ('修改后的数组是:')
a = a.reshape(3,4) 
print(a)

输出:

原始数组是:
[ 0  5 10 15 20 25 30 35 40 45 50 55]


修改后的数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]

numpy.ndarray.flat是一个数组元素迭代器,实例如下:

import numpy as np

a=np.arange(0,60,5).reshape(3,4)
print('第一个数组为:')
for row in a:
    print(row)
print('------')

print('迭代后的数组为:')
# 对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器
for element in a.flat:
    print(element)

输出:

第一个数组为:
[ 0  5 10 15]
[20 25 30 35]
[40 45 50 55]
------
迭代后的数组为:
0
5
10
15
20
25
30
35
40
45
50
55

numpy.ndarray.flatten返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,格式如下:

ndarray.flatten(order='C')

参数order:‘C’–按行,‘F’–按列,‘A’–原顺序,‘K’–元素在内存中的出现顺序。

import numpy as np 
a = np.arange(0,60,5).reshape(3,4) 
print ('原始数组是:')
print (a)
print ('\n')

print('展开的数组为:')
print(a.flatten())
print ('\n-----')
print('以F风格顺序展开的数组:')
print(a.flatten(order='F'))

输出:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


展开的数组为:
[ 0  5 10 15 20 25 30 35 40 45 50 55]

-----
以F风格顺序展开的数组:
[ 0 20 40  5 25 45 10 30 50 15 35 55]

numpy.ravel()展平的数组元素,顺序通常是"C风格",返回的是数组视图,修改会影响原始数组。该函数接收两个参数:

numpy.ravel(a,order='C')

参数order:‘C’–按行,‘F’–按列,‘A’–原顺序,‘K’–元素在内存中的出现顺序。

import numpy as np 
a = np.arange(0,60,5).reshape(3,4) 
print ('原始数组是:')
print (a)
print ('\n')

print('调用ravel后:')
print(a.ravel())
print ('\n-----')
print('以F风格顺序调用ravel后:')
print(a.ravel(order='F'))

输出:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


调用ravel后:
[ 0  5 10 15 20 25 30 35 40 45 50 55]

-----
以F风格顺序调用ravel后:
[ 0 20 40  5 25 45 10 30 50 15 35 55]

2.2 翻转数组

函数描述
transpose对换数组的维度,即转置
ndarray.T和self.transpose()相同
rollaxis向后滚动指定的轴
swapaxes对换数组的两个轴

numpy.transpose函数用于对换数组的维度,格式如下:

numpy.transpose(arr,axes)

参数说明:

1、arr:要操作的数组

2、axes:整数列表,对应维度,通常所有维度都会对换。

import numpy as np 
a = np.arange(0,60,5).reshape(3,4) 
print ('原始数组是:')
print (a)
print ('\n')

print('转置后:')
print(np.transpose(a))

输出:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


转置后:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]

numpy.ndarray.T类似numpy.transpose:

import numpy as np 
a = np.arange(0,60,5).reshape(3,4) 
print ('原始数组是:')
print (a)
print ('\n')

print('转置后:')
print(a.T)

输出:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


转置后:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]

numpy.rollaxis函数向后滚动特定的轴到一个特定位置,格式如下:

numpy.rollaxis(arr,axis,start)

参数说明:

1、arr:数组

2、axis:要向后滚动的轴,其它轴的相对位置不会改变

3、start:默认为零,表示完整的滚动,否则会滚动到特定位置。

我认为示例代码过于复杂,且以后用到的可能性较小,因此不整理该内容,以后用到再说。

numpy.swapaxes函数用于交换数组的两个轴,格式如下:

numpy.swapaxes(arr,axis1,axis2)

参数说明:

1、arr:输入的数组

2、axis1:对应第一个轴的整数

3、axis2:对应第二个轴的整数

import numpy as np 
a = np.arange(8).reshape(2,4) 
print ('原始数组是:')
print (a)
print ('-------')

print('调用swapaxes函数后的数组:')
b=np.swapaxes(a,0,1) #这里与转置效果相同
print(b)

输出:

原始数组是:
[[0 1 2 3]
 [4 5 6 7]]
-------
调用swapaxes函数后的数组:
[[0 4]
 [1 5]
 [2 6]
 [3 7]]

2.3 修改数组维度

维度描述
broadcast产生模仿广播的对象
broadcast_to将数组广播到新形状
expand_dims扩展数组的形状
squeeze从数组的形状中删除一维条目

下面只介绍squeeze,其他看这里

numpy.squeeze函数从给定数组的形状中删除一维的条目,函数格式如下:

numpy.squeeze(arr,axis)

参数说明:

1、arr:输入数组

2、axis:整数或整数元组,用于选择形状中一维条目的子集

import numpy as np

x=np.arange(9).reshape(1,3,3)
print('数组x:')
print(x)

y=np.squeeze(x)
print('\n数组y:')
print(y)

print('\n数组x、y的形状分别为:')
print(x.shape,y.shape)

输出:

数组x:
[[[0 1 2]
  [3 4 5]
  [6 7 8]]]

数组y:
[[0 1 2]
 [3 4 5]
 [6 7 8]]

数组x、y的形状分别为:
(1, 3, 3) (3, 3)

2.4 连接数组

函数描述
concatenate连接沿现有轴的数组序列
stack沿着新的轴加入一系列数组。
hstack水平堆叠序列中的数组(列方向)
vstack竖直堆叠序列中的数组(行方向)

numpy.concatenate函数用于沿指定轴连接相同形状的两个或多个数组,格式如下:

numpy.concatenate((a1,a2,...),axis)

参数说明:

1、a1,a2,…:相同类型的数组

2、axis:沿着它连接数组的轴,默认为0

import numpy as np

a=np.array([[1,2],[3,4]])
print('第一个数组:')
print(a)
print('------')

b=np.array([[5,6],[7,8]])
print('第二个数组:')
print(b)
print('------')

print('沿轴0连接两个数组:')
print(np.concatenate((a,b)))
print('------')
print('沿轴1连接两个数组:')
print(np.concatenate((a,b),axis=1))

输出:

第一个数组:
[[1 2]
 [3 4]]
------
第二个数组:
[[5 6]
 [7 8]]
------
沿轴0连接两个数组:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
------
沿轴1连接两个数组:
[[1 2 5 6]
 [3 4 7 8]]

只介绍concatenate,其他看这里

2.5 分割数组

函数数组及操作
split将一个数组分割为多个子数组
hsplit将一个数组水平分割为多个子数组(按列)
vsplit将一个数组垂直分割为多个子数组(按行)

numpy.split函数沿特定的轴将数组分割为子数组,格式如下:

numpy.split(ary,indices_or_sections,axis)

参数说明:

1、ary:被分割的数组

2、indices_or_sections:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)

3、axis:设置沿着哪个方向进行切分,默认为0,横向切分,即水平方向。为1时,纵向切分,即竖直方向。

a=np.arange(9)
print('第一个数组:')
print(a)
print('---------')

b=np.split(a,3)
print('将数组分为三个大小相同的子数组:')
print(b)
print('---------')

b=np.split(a,[2,4,7])
print('将数组在一维数组中表明的位置分割:')
print(b)

输出:

第一个数组:
[0 1 2 3 4 5 6 7 8]
---------
将数组分为三个大小相同的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
---------
将数组在一维数组中表明的位置分割:
[array([0, 1]), array([2, 3]), array([4, 5, 6]), array([7, 8])]

axis为0时在水平方向分割,axis为1时在垂直方向分割:

a=np.arange(16).reshape(4,4)
print('第一个数组:')
print(a)
print('---------')

b=np.split(a,2)
print('默认分割,即按0轴/水平方向分割:')
print(b)
print('---------')

c=np.split(a,2,1)
print('沿垂直方向分割:')
print(c)
print('---------')

d=np.split(a,2,0)
print('沿水平方向分割:')
print(d)

输出:

第一个数组:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
---------
默认分割,即按0/水平方向分割:
[array([[0, 1, 2, 3],
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])]
---------
沿垂直方向分割:
[array([[ 0,  1],
       [ 4,  5],
       [ 8,  9],
       [12, 13]]), array([[ 2,  3],
       [ 6,  7],
       [10, 11],
       [14, 15]])]
---------
沿水平方向分割:
[array([[0, 1, 2, 3],
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])]

numpy.hsplit函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。

import numpy as np

harr=np.floor(10*np.random.random((2,6)))
print('原array:')
print(harr)

print('\n\n拆分后:')
print(np.hsplit(harr,3))

输出:

原array:
[[5. 9. 4. 4. 7. 8.]
 [1. 2. 9. 4. 2. 0.]]


拆分后:
[array([[5., 9.],
       [1., 2.]]), array([[4., 4.],
       [9., 4.]]), array([[7., 8.],
       [2., 0.]])]

numpy.vsplit沿着垂直轴分割,其分割方式与hsplit用法相同。

import numpy as np

harr=np.floor(10*np.random.random((4,6)))
print('原array:')
print(harr)

print('\n\n拆分后:')
print(np.vsplit(harr,2))

输出:

原array:
[[3. 0. 4. 4. 2. 8.]
 [1. 0. 2. 0. 8. 5.]
 [5. 9. 7. 2. 4. 5.]
 [3. 1. 5. 3. 9. 5.]]


拆分后:
[array([[3., 0., 4., 4., 2., 8.],
       [1., 0., 2., 0., 8., 5.]]), array([[5., 9., 7., 2., 4., 5.],
       [3., 1., 5., 3., 9., 5.]])]

2.6 数组元素的添加与删除

函数元素及描述
resize返回指定形状的新数组
append将值添加到数组末尾
insert沿指定轴将值插入到指定下标之前
delete删掉某个轴的子数组,并返回删除后的新数组
unique查找数组内的唯一元素

numpy.resize函数返回指定大小的新数组。如果新数组大小大于原始大小,则包含原始数组中的元素的副本

numpy.resize(arr,shape)

参数说明:

1、arr:要修改大小的数组

2、shape:返回数组的新形状

a=np.array([[1,2,3],[4,5,6]])
print('第一个数组:')
print(a)
print('-----')

print('第一个数组的形状:')
print(a.shape)
print('-----')

b=np.resize(a,(3,2))
print('第二个数组:')
print(b)
print('-----')

print('第二个数组的形状:')
print(b.shape)
print('-----')

b=np.resize(a,(3,3))
print('修改第二个数组的形状后:')
print(b) #注意在输出中,a的第一行在b中重复出现,因为尺寸变大了

输出:

第一个数组:
[[1 2 3]
 [4 5 6]]
-----
第一个数组的形状:
(2, 3)
-----
第二个数组:
[[1 2]
 [3 4]
 [5 6]]
-----
第二个数组的形状:
(3, 2)
-----
修改第二个数组的形状后:
[[1 2 3]
 [4 5 6]
 [1 2 3]]

numpy.append函数在数组的末尾添加值。追加操作会分配整个数组,并把原来的数组复制到新数组中。此外,输入数组的维度必须匹配,否则将生成ValueError。

numpy.append(arr,values,axis=None)

参数说明:

1、arr:输入数组

2、values:要向arr添加的值,需要和arr形状相同(除了要添加的轴)

3、axis:默认为None,此时默认是横向追加,返回【总是为一维数组】;当axis为0时,数组是加在下边(列数要相同);当axis为1时,数组是加在右边(行数要相同)。

a=np.array([[1,2,3],[4,5,6]])
print('第一个数组:')
print(a)

print('\n\n向数组添加元素:')
print(np.append(a,[7,8,9]))

print('\n\n沿轴0添加元素:')
print(np.append(a,[[7,8,9]],axis=0))

print('\n\n沿轴1添加元素:')
print(np.append(a,[[5,5,5],[7,8,9]],axis=1))

输出:

第一个数组:
[[1 2 3]
 [4 5 6]]


向数组添加元素:
[1 2 3 4 5 6 7 8 9]


沿轴0添加元素:
[[1 2 3]
 [4 5 6]
 [7 8 9]]


沿轴1添加元素:
[[1 2 3 5 5 5]
 [4 5 6 7 8 9]]

numpy.insert函数在给定索引之前,沿给定轴在输入数组中插入值;如果未提供轴,则输入数组会被展开。

numpy.insert(arr,obj,values,axis)

参数说明:

1、arr:输入数组

2、obj:在其之前插入值的索引

3、values:要插入的值

4、axis:沿着它插入的轴,如果未提供,则输入数组会被展开

a=np.array([[1,2],[3,4],[5,6]])

print('第一个数组:')
print(a)

print('\n未传递Axis参数。在插入之前输入数组会被展开')
print(np.insert(a,3,[11,12]))

print('\n传递了Axis参数。会广播值数组来分配输入数组')

print('\n沿轴0广播')
print(np.insert(a,1,[11],axis=0))

print('\n沿轴1广播')
print(np.insert(a,1,11,axis=1))

输出:

第一个数组:
[[1 2]
 [3 4]
 [5 6]]

未传递Axis参数。在插入之前输入数组会被展开
[ 1  2  3 11 12  4  5  6]

传递了Axis参数。会广播值数组来分配输入数组

沿轴0广播
[[ 1  2]
 [11 11]
 [ 3  4]
 [ 5  6]]

沿轴1广播
[[ 1 11  2]
 [ 3 11  4]
 [ 5 11  6]]

numpy.delete函数返回从输入数组中删除指定子数组后的新数组。如果未提供轴参数,则输入数组将展开。

np.delete(arr,obj,axis)

参数说明:

1、arr:输入数组

2、obj:可以是切片,整数或者整数数组,表明要从输入数组删除的子数组

3、axis:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开

a=np.arange(12).reshape(3,4)

print('第一个数组:')
print(a)

print('\n未传递Axis参数。在删除之前输入数组会被展开')
print(np.delete(a,5))

print('\n删除第二列')
print(np.delete(a,1,axis=1))

print('\n包含从数组中删除的替代值的切片')
a=np.arange(1,11)
print(np.delete(a,np.s_[::2])) #s_是切片slice

输出:

第一个数组:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

未传递Axis参数。在删除之前输入数组会被展开
[ 0  1  2  3  4  6  7  8  9 10 11]

删除第二列
[[ 0  2  3]
 [ 4  6  7]
 [ 8 10 11]]

包含从数组中删除的替代值的切片
[ 2  4  6  8 10]

numpy.unique函数用于去除数组中的重复元素。

np.unique(arr,return_index,return_inverse,return_counts)

1、arr:输入数组,如果不是一维数组则会展开,还会从小到大排序

2、return_index:如果为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储

3、return_inverse:如果为true,返回旧列表元素在新列表中的位置(下标),并以列表形式储

4、return_counts:如果为true,返回去重数组中的元素在原数组中的出现次数

import numpy as np

a=np.array([5,2,6,2,7,5,6,8,2,9])
print('第一个数组:')
print(a)

print('\n第一个数组去掉重复值后:')
u=np.unique(a)
print(u)

print('\n去重得到的数组的索引数组:')
u,indices=np.unique(a,return_index=True)
print(indices)

print('\n每个和原数组下标对应的数值:')
print(a)

print('\n去重数组的下标:')
u,indices=np.unique(a,return_inverse=True)
print(u)

print('\n下标为:')
print(indices)

print('\n使用下标重构原数组:')
print(u[indices])

print('\n返回去重元素的重复数量:')
u,indices=np.unique(a,return_counts=True)
print(u)
print(indices)

输出:

第一个数组:
[5 2 6 2 7 5 6 8 2 9]

第一个数组去掉重复值后:
[2 5 6 7 8 9]

去重得到的数组的索引数组:
[1 0 2 4 7 9]

每个和原数组下标对应的数值:
[5 2 6 2 7 5 6 8 2 9]

去重数组的下标:
[2 5 6 7 8 9]

下标为:
[1 0 2 0 3 1 2 4 0 5]

使用下标重构原数组:
[5 2 6 2 7 5 6 8 2 9]

返回去重元素的重复数量:
[2 5 6 7 8 9]
[3 2 2 1 1 1]

END

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值