前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Numpy初探

Numpy初探

作者头像
用户3577892
发布2020-06-11 12:18:25
2K0
发布2020-06-11 12:18:25
举报
文章被收录于专栏:数据科学CLUB数据科学CLUB

理解Python中的数据类型Python代码Python代码Python整型不仅仅是一个整型Python列表不仅仅是一个列表Python中的固定类型数组从Python列表创建数组创建数组从头创建数组NumPy标准数据类型numpy数组的基本操作NumPy数组的属性数组索引:获取单个元素数组切片:获取子数组非副本视图的子数组创建数组的副本数组的变形数组拼接和分裂

《Python数据科学手册》读书笔记

理解Python中的数据类型

要实现高效的数据驱动科学和计算,需要理解数据是如何被存储和操作的。

Python 的用户往往被其易用性所吸引, 其中一个易用之处就在于动态输入。静态类型的语言(如 C 或 Java) 往往需要每一个变量都明确地声明, 而动态类型的语言(例如 Python) 可以跳过这个特殊规定。例如在C 语言中, 你可能会按照如下方式指定一个特殊的操作:

代码语言:javascript
复制
/* C代码 */
int result = 0;
for(int i=0; i<100; i++){
result += i;
}

而在 Python 中, 同等的操作可以按照如下方式实现:

Python代码

代码语言:javascript
复制
result = 0
for i in range(100):
result += i

注意这里最大的不同之处:在 C 语言中, 每个变量的数据类型被明确地声明;而在 Python 中, 类型是动态推断的。这意味着可以将任何类型的数据指定给任何变量:

Python代码

代码语言:javascript
复制
x = 4
x = "four

这里已经将 x 变量的内容由整型转变成了字符串, 而同样的操作在 C语言中将会导致编译错误或其他未知的后果:

代码语言:javascript
复制
/* C代码 */
int x = 4;
x = "four"; // 编译失败

这种灵活性是使 Python 和其他动态类型的语言更易用的原因之一。但是这种类型灵活性也指出了一个事实:Python 变量不仅是它们的 值, 还包括了关于值的类型的一些额外信息。

Python整型不仅仅是一个整型

标准的 Python 实现是用 C 语言编写的。这意味着每一个 Python 对象都是一个聪明的伪 C 语言结构体, 该结构体不仅包含其值, 还有其他信息。例如, 当我们在 Python 中定义一个整型, 例如 x = 10000 时, x并不是一个“原生”整型, 而是一个指针, 指向一个 C 语言的复合结构体, 结构体里包含了一些值。查看 Python 3.4 的源代码, 可以发现整型(长整型) 的定义, 如下所示 :

代码语言:javascript
复制
struct _longobject {
long ob_refcnt;
PyTypeObject *ob_type;
size_t ob_size;
long ob_digit[1];
};

Python 3.4 中的一个整型实际上包括 4 个部分。

  • ob_refcnt 是一个引用计数, 它帮助 Python 默默地处理内存的分 配和回收。
  • ob_type 将变量的类型编码。
  • ob_size 指定接下来的数据成员的大小。
  • ob_digit 包含我们希望 Python 变量表示的实际整型值。

这意味着与 C 语言这样的编译语言中的整型相比, 在 Python 中存储一个整型会有一些开销。

两者的差异在于, C 语言整型本质上是对应某个内存位置的标签, 里面存储的字节会编码成整型。而 Python 的整型其实是一个指针, 指向包含这个 Python 对象所有信息的某个内存位置, 其中包括可以转换成整型的字节。 由于 Python 的整型结构体里面还包含了大量额外的信息,所以 Python 可以自由、 动态地编码。但是, Python 类型中的这些额外信息也会成为负担, 在多个对象组合的结构体中尤其明显。

Python列表不仅仅是一个列表

设想如果使用一个包含很多 Python 对象的 Python 数据结构, 会发生什么?Python 中的标准可变多元素容器是列表。可以用如下方式创建一个整型值列表:

代码语言:javascript
复制
L = list(range(10))
L
代码语言:javascript
复制
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
代码语言:javascript
复制
 type(L[0])
代码语言:javascript
复制
int

或者创建一个字符串列表:

代码语言:javascript
复制
L2 = [str(c) for c in L]
L2
代码语言:javascript
复制
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
代码语言:javascript
复制
 type(L2[0])
代码语言:javascript
复制
str

因为 Python 的动态类型特性, 甚至可以创建一个异构的列表:

代码语言:javascript
复制
L3 = [True, "2", 3.0, 4]
[type(item) for item in L3]
代码语言:javascript
复制
[bool, str, float, int]

但是想拥有这种灵活性也是要付出一定代价的:为了获得这些灵活的类型, 列表中的每一项必须包含各自的类型信息、 引用计数和其他信息;也就是说, 每一项都是一个完整的 Python 对象。来看一个特殊的例子, 如果列表中的所有变量都是同一类型的, 那么很多信息都会显得多余,这时将数据存储在固定类型的数组中应该会更高效。

在实现层面, 数组基本上包含一个指向连续数据块的指针。另一方面,Python 列表包含一个指向指针块的指针, 这其中的每一个指针对应一个完整的 Python 对象 。另外, 列表的优势是灵活, 因为每个列表元素是一个包含数据和类型信息的完整结构体,而且列表可以用任意类型的数据填充。固定类型的 NumPy 式数组缺乏这种灵活性, 但是能更有效地存储和操作数据。

Python中的固定类型数组

Python 提供了几种将数据存储在有效的、 固定类型的数据缓存中的选项。内置的数组(array) 模块 可以用于创建统一类型的密集数组:

代码语言:javascript
复制
import array
L = list(range(10))
A = array.array('i', L)
A
代码语言:javascript
复制
array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

这里的 'i' 是一个数据类型码, 表示数据为整型。更实用的是 NumPy 包中的 ndarray 对象。Python 的数组对象提供了数组型数据的有效存储, 而 NumPy 为该数据加上了高效的操作。稍后将介绍这些操作, 这里先展示几种创建 NumPy 数组的方法。

代码语言:javascript
复制
import numpy as np
# 查看numpy的版本
np.__version__
代码语言:javascript
复制
'1.15.1'
代码语言:javascript
复制
# 获取numpy教程
np?

从Python列表创建数组创建数组

首先, 可以用 np.array 从 Python 列表创建数组:

代码语言:javascript
复制
np.array([1,2,3,4,5])
代码语言:javascript
复制
array([1, 2, 3, 4, 5])

numpy要求数组必须包含同一类型的数据,如果类型不匹配将会向上转换

代码语言:javascript
复制
np.array([1.2,2,3,4,5])
代码语言:javascript
复制
array([1.2, 2. , 3. , 4. , 5. ])

可以使用dtype改变数组的数据类型

代码语言:javascript
复制
np.array([1,2,3,4,5],dtype='float32')
代码语言:javascript
复制
array([1., 2., 3., 4., 5.], dtype=float32)

不同于 Python 列表, NumPy 数组可以被指定为多维的。以下是用列表的列表初始化多维数组的一种方法:

代码语言:javascript
复制
np.array([range(i,i+3) for i in [2,4,6]])
代码语言:javascript
复制
array([[2, 3, 4],
       [4, 5, 6],
       [6, 7, 8]])

内层的列表被当作二维数组的行。

从头创建数组

面对大型数组的时候, 用 NumPy 内置的方法从头创建数组是一种更高效的方法。以下是几个示例:

代码语言:javascript
复制
# 创建一个所有值为0,长度为10的数组
np.zeros(10,dtype=int)
代码语言:javascript
复制
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
代码语言:javascript
复制
# 创建一个3行5列所有值为1的浮点数组
np.ones((3,5),dtype=float)
代码语言:javascript
复制
array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
代码语言:javascript
复制
# 创建一个3行5列的浮点数组,数组的值都是3.14
np.full((3,5),3.14)
代码语言:javascript
复制
array([[3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14],
       [3.14, 3.14, 3.14, 3.14, 3.14]])
代码语言:javascript
复制
# 创建一个数组从0开始到20结束,步长为2
np.arange(0, 20, 2)
代码语言:javascript
复制
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
代码语言:javascript
复制
# 创建一个有5个元素的数组,5个数均匀分配到0~1之间
np.linspace(0, 1, 5)
代码语言:javascript
复制
array([0.  , 0.25, 0.5 , 0.75, 1.  ])
代码语言:javascript
复制
# 创建一个3*3的数组,个元素服从0~1上的均匀分布
np.random.random((3, 3))
代码语言:javascript
复制
array([[0.69872258, 0.0299473 , 0.99635603],
       [0.25231312, 0.90566931, 0.30884748],
       [0.54470709, 0.64877725, 0.48333009]])
代码语言:javascript
复制
# 创建一个3*3的数组,个元素服从均值为0,标准差为1
np.random.normal(0, 1, (3, 3))
代码语言:javascript
复制
array([[ 0.59378053, -0.82101116,  0.28096713],
       [ 0.72447884, -0.29206219,  0.86922837],
       [-0.82404414,  1.26396153,  0.66129599]])
代码语言:javascript
复制
# 创建一个3*3的整数数组,个元素服从0~10上的均匀分布
np.random.randint(0, 10, (3, 3))
代码语言:javascript
复制
array([[1, 5, 0],
       [9, 6, 5],
       [1, 5, 4]])
代码语言:javascript
复制
# 创建一个3*3的单位矩阵
np.eye(3)
代码语言:javascript
复制
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

NumPy标准数据类型

NumPy 数组包含同一类型的值, 因此详细了解这些数据类型及其限制是非常重要的。

数据类型

描述

bool_

Boolean (True or False) stored as a byte

int_

Default integer type (same as C long; normally either int64 or int32)

intc

Identical to C int (normally int32 or int64)

intp

Integer used for indexing (same as C ssize_t; normally either int32 or int64)

int8

Byte (-128 to 127)

int16

Integer (-32768 to 32767)

int32

Integer (-2147483648 to 2147483647)

int64

Integer (-9223372036854775808 to 9223372036854775807)

uint8

Unsigned integer (0 to 255)

uint16

Unsigned integer (0 to 65535)

uint32

Unsigned integer (0 to 4294967295)

uint64

Unsigned integer (0 to 18446744073709551615)

float_

Shorthand for float64.

float16

Half precision float: sign bit, 5 bits exponent, 10 bits mantissa

float32

Single precision float: sign bit, 8 bits exponent, 23 bits mantissa

float64

Double precision float: sign bit, 11 bits exponent, 52 bits mantissa

complex_

Shorthand for complex128.

complex64

Complex number, represented by two 32-bit floats

complex128

Complex number, represented by two 64-bit floats

numpy数组的基本操作

  • 数组的属性

确定数组的大小、 形状、 存储大小、 数据类型。

  • 数组的索引

获取和设置数组各个元素的值。

  • 数组的切分

在大的数组中获取或设置更小的子数组。

  • 数组的变形

改变给定数组的形状。

  • 数组的拼接和分裂

将多个数组合并为一个, 以及将一个数组分裂成多个

NumPy数组的属性

首先介绍一些有用的数组属性。定义三个随机的数组:一个一维数组、一个二维数组和一个三维数组。将用 NumPy 的随机数生成器设置 一组种子值, 以确保每次程序执行时都可以生成同样的随机数组:

代码语言:javascript
复制
import numpy as np
np.random.seed(0)  

x1 = np.random.randint(10, size=6)  
x2 = np.random.randint(10, size=(3, 4))  
x3 = np.random.randint(10, size=(3, 4, 5))
代码语言:javascript
复制
print("x3 ndim: ", x3.ndim) #数组维度
print("x3 shape:", x3.shape) #数组每个维度的大小
print("x3 size: ", x3.size) #数组的总大小
print("dtype:", x3.dtype) #数组的数据类型
print("itemsize:", x3.itemsize, "bytes") #每个元素的字节大小
print("nbytes:", x3.nbytes, "bytes") #数组总字节大小
代码语言:javascript
复制
x3 ndim:  3
x3 shape: (3, 4, 5)
x3 size:  60
dtype: int32
itemsize: 4 bytes
nbytes: 240 bytes

数组索引:获取单个元素

代码语言:javascript
复制
x1
代码语言:javascript
复制
array([5, 0, 3, 3, 7, 9])
代码语言:javascript
复制
x1[0]
代码语言:javascript
复制
5
代码语言:javascript
复制
x1[-1]
代码语言:javascript
复制
9
代码语言:javascript
复制
x2
代码语言:javascript
复制
array([[3, 5, 2, 4],
       [7, 6, 8, 8],
       [1, 6, 7, 7]])
代码语言:javascript
复制
x2[0,0]
代码语言:javascript
复制
3
代码语言:javascript
复制
x2[2,-1]
代码语言:javascript
复制
7
代码语言:javascript
复制
# 修改元素
x2[0,0] = 12
x2
代码语言:javascript
复制
array([[12,  5,  2,  4],
       [ 7,  6,  8,  8],
       [ 1,  6,  7,  7]])

请注意, 和 Python 列表不同, NumPy 数组是固定类型的。这意味着当你试图将一个浮点值插入一个整型数组时, 浮点值会被截短成整型。 并且这种截短是自动完成的, 不会给你提示或警告, 所以需要特别注意这一点!

代码语言:javascript
复制
x1[0] = 3.14
x1
代码语言:javascript
复制
array([3, 0, 3, 3, 7, 9])

数组切片:获取子数组

  • x[start:stop:step]
  1. 一维子数组
代码语言:javascript
复制
x = np.arange(10)
x
代码语言:javascript
复制
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
代码语言:javascript
复制
# 前5个元素
x[:5]
代码语言:javascript
复制
array([0, 1, 2, 3, 4])
代码语言:javascript
复制
# 索引5之后的元素,包括索引5
x[5:]
代码语言:javascript
复制
array([5, 6, 7, 8, 9])
代码语言:javascript
复制
x[4:7]
代码语言:javascript
复制
array([4, 5, 6])
代码语言:javascript
复制
x[::2]
代码语言:javascript
复制
array([0, 2, 4, 6, 8])
代码语言:javascript
复制
x[1::2]
代码语言:javascript
复制
array([1, 3, 5, 7, 9])
代码语言:javascript
复制
#将所有元素逆序
x[::-1]
代码语言:javascript
复制
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
代码语言:javascript
复制
x[5::-2]
代码语言:javascript
复制
array([5, 3, 1])
  1. 多维子数组
代码语言:javascript
复制
x2
代码语言:javascript
复制
array([[12,  5,  2,  4],
       [ 7,  6,  8,  8],
       [ 1,  6,  7,  7]])
代码语言:javascript
复制
# 两行,三列
x2[:2, :3]
代码语言:javascript
复制
array([[12,  5,  2],
       [ 7,  6,  8]])
代码语言:javascript
复制
# 所有行,前三列
x2[:, :3]
代码语言:javascript
复制
array([[12,  5,  2],
       [ 7,  6,  8],
       [ 1,  6,  7]])
代码语言:javascript
复制
x2[::-1, ::-1]
代码语言:javascript
复制
array([[ 7,  7,  6,  1],
       [ 8,  8,  6,  7],
       [ 4,  2,  5, 12]])
  1. 获取数组的行和列
代码语言:javascript
复制
# x2的第一列
x2[:,0]
代码语言:javascript
复制
array([12,  7,  1])
代码语言:javascript
复制
# x2的第一行
x2[0,:]
代码语言:javascript
复制
array([12,  5,  2,  4])
代码语言:javascript
复制
# 等价于print(x2[0,:])
x2[0]
代码语言:javascript
复制
array([12,  5,  2,  4])

非副本视图的子数组

关于数组切片有一点很重要也非常有用, 那就是数组切片返回的是数组数据的视图, 而不是数值数据的副本。这一点也是 NumPy 数组切片和 Python 列表切片的不同之处:在 Python 列表中, 切片是值的副本。例如此前示例中的那个二维数组:

代码语言:javascript
复制
x2
代码语言:javascript
复制
array([[12,  5,  2,  4],
       [ 7,  6,  8,  8],
       [ 1,  6,  7,  7]])
代码语言:javascript
复制
x2_sub = x2[:2,:2]
x2_sub
代码语言:javascript
复制
array([[12,  5],
       [ 7,  6]])
代码语言:javascript
复制
# 修改子数组
x2_sub[0, 0] = 3.14
x2_sub
代码语言:javascript
复制
array([[3, 5],
       [7, 6]])
代码语言:javascript
复制
# 可以发现原始数组也被修改了!
x2
代码语言:javascript
复制
array([[3, 5, 2, 4],
       [7, 6, 8, 8],
       [1, 6, 7, 7]])

这种默认的处理方式实际上非常有用:它意味着在处理非常大的数据集时, 可以获取或处理这些数据集的片段, 而不用复制底层的数据缓存。

创建数组的副本

尽管数组视图有一些非常好的特性, 但是在有些时候明确地复制数组里的数据或子数组也是非常有用的。可以很简单地通过 copy()方法实现:

代码语言:javascript
复制
x2_sub_copy = x2[:2, :2].copy()
x2_sub_copy
代码语言:javascript
复制
array([[3, 5],
       [7, 6]])
代码语言:javascript
复制
x2_sub_copy[0, 0] = 5.2
x2_sub_copy
代码语言:javascript
复制
array([[5, 5],
       [7, 6]])
代码语言:javascript
复制
# 修改子数组,但原始数组没有发生改变
x2
代码语言:javascript
复制
array([[3, 5, 2, 4],
       [7, 6, 8, 8],
       [1, 6, 7, 7]])

数组的变形

另一个有用的操作类型是数组的变形。数组变形最灵活的实现方式是通过 reshape() 函数来实现。例如, 如果你希望将数字 1~9 放入一个3×3 的矩阵中, 可以采用如下方法:

代码语言:javascript
复制
grid = np.arange(1, 10).reshape((3, 3))
grid
代码语言:javascript
复制
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

请注意, 如果希望该方法可行, 那么原始数组的大小必须和变形后数组的大小一致。如果满足这个条件, reshape 方法将会用到原始数组的一个非副本视图。但实际情况是, 在非连续的数据缓存的情况下, 返回非副本视图往往不可能实现。

另外一个常见的变形模式是将一个一维数组转变为二维的行或列的矩阵。你也可以通过 reshape 方法来实现, 或者更简单地在一个切片操作中利用 newaxis 关键字:

代码语言:javascript
复制
x = np.array([1, 2, 3])

# 通过变形获得行向量
x.reshape((1, 3))
代码语言:javascript
复制
array([[1, 2, 3]])
代码语言:javascript
复制
# 通过newaxis获得行向量
x[np.newaxis, :]
代码语言:javascript
复制
array([[1, 2, 3]])
代码语言:javascript
复制
# 通过变形获得行向量
x.reshape((3, 1))
代码语言:javascript
复制
array([[1],
       [2],
       [3]])
代码语言:javascript
复制
# 通过newaxis获得行向量
x[:, np.newaxis]
代码语言:javascript
复制
array([[1],
       [2],
       [3]])

数组拼接和分裂

以上所有的操作都是针对单一数组的, 但有时也需要将多个数组合并为一个, 或将一个数组分裂成多个。接下来将详细介绍这些操作。

  1. 数组的拼接

拼接或连接 NumPy 中的两个数组主要由 np.concatenate、np.vstack 和 np.hstack 例程实现。np.concatenate 将数组元组或数组列表作为第一个参数, 如下所示:

代码语言:javascript
复制
x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
np.concatenate([x, y])
代码语言:javascript
复制
array([1, 2, 3, 3, 2, 1])
代码语言:javascript
复制
z = [99, 99, 99]
np.concatenate([x, y, z])
代码语言:javascript
复制
array([ 1,  2,  3,  3,  2,  1, 99, 99, 99])
代码语言:javascript
复制
grid = np.array([[1, 2, 3],
                 [4, 5, 6]])
代码语言:javascript
复制
# 沿着第一个轴拼接
np.concatenate([grid, grid])
代码语言:javascript
复制
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
代码语言:javascript
复制
# 沿着第二个轴拼接
np.concatenate([grid, grid], axis=1)
代码语言:javascript
复制
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])

沿着固定维度处理数组时, 使用 np.vstack(垂直栈) 和np.hstack(水平栈) 函数会更简洁:

代码语言:javascript
复制
x = np.array([1, 2, 3])
grid = np.array([[9, 8, 7],
                 [6, 5, 4]])

# 垂直栈数组
np.vstack([x, grid])
代码语言:javascript
复制
array([[1, 2, 3],
       [9, 8, 7],
       [6, 5, 4]])
代码语言:javascript
复制
# 水平栈数组
y = np.array([[99],
              [99]])
np.hstack([grid, y])
代码语言:javascript
复制
array([[ 9,  8,  7, 99],
       [ 6,  5,  4, 99]])

与之类似, np.dstack 将沿着第三个维度拼接数组。

  1. 数组的分裂

与拼接相反的过程是分裂。分裂可以通过 np.split、 np.hsplit和 np.vsplit 函数来实现。可以向以上函数传递一个索引列表作为参数, 索引列表记录的是分裂点位置:

代码语言:javascript
复制
x = [1, 2, 3, 99, 99, 3, 2, 1]
x1, x2, x3 = np.split(x, [3, 5])# 用索引列表记录分裂点的位置
print(x1, x2, x3)
代码语言:javascript
复制
[1 2 3] [99 99] [3 2 1]

值得注意的是, N 分裂点会得到 N + 1 个子数组。相关的np.hsplit 和 np.vsplit 的用法也类似:

代码语言:javascript
复制
grid = np.arange(16).reshape((4, 4))
grid
代码语言:javascript
复制
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
代码语言:javascript
复制
upper, lower = np.vsplit(grid, [2])
print(upper)
print(lower)
代码语言:javascript
复制
[[0 1 2 3]
 [4 5 6 7]]
[[ 8  9 10 11]
 [12 13 14 15]]
代码语言:javascript
复制
left, right = np.hsplit(grid, [2])
print(left)
print(right)
代码语言:javascript
复制
[[ 0  1]
 [ 4  5]
 [ 8  9]
 [12 13]]
[[ 2  3]
 [ 6  7]
 [10 11]
 [14 15]]

np.dsplit将沿数组第三个维度进行分裂

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据科学CLUB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 理解Python中的数据类型
  • Python代码
  • Python代码
    • Python整型不仅仅是一个整型
      • Python列表不仅仅是一个列表
        • Python中的固定类型数组
          • 从Python列表创建数组创建数组
            • 从头创建数组
              • NumPy标准数据类型
              • numpy数组的基本操作
                • NumPy数组的属性
                  • 数组索引:获取单个元素
                    • 数组切片:获取子数组
                      • 非副本视图的子数组
                        • 创建数组的副本
                          • 数组的变形
                            • 数组拼接和分裂
                            相关产品与服务
                            数据保险箱
                            数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档