- 科学计算
- 数据分析
【免费下载链接】numpy
The fundamental package for scientific computing with Python.
导读
numpy.genfromtxt是 NumPy 提供的从文本文件(CSV、固定宽度文件、压缩归档等)创建数组的核心函数,其最大的特色是在导入过程中显式处理缺失数据、自定义列名与逐列类型转换。本文将基于 NumPy 官方用户指南中 Importing data with numpy.genfromtxt 的完整内容,结合 NumPy 源码实现(numpy/lib/_npyio_impl.py、numpy/lib/_iotools.py)与测试用例(numpy/lib/tests/test_io.py),系统讲解输入定义、行分割、列选择、类型推断、列命名与缺失值/填充值机制,让你能处理从简单 CSV 到带注释、缺项、异构类型数据的一切日常导入场景。
本文示例沿用官方文档约定:
import numpy as np与from io import StringIO,后文不再重复这两行导入。
总体机制:双循环架构
NumPy 提供多个从表格数据创建数组的函数(如numpy.loadtxt),本文聚焦于genfromtxt。从整体架构看,genfromtxt依次执行两个主循环(官方文档原话 "runs two main loops"):
- 第一个循环把文件中的每一行转换成一个字符串序列(即按
delimiter分割为列); - 第二个循环把每个字符串按对应的
dtype转换为合适的数据类型。
这一机制比单循环的实现(如numpy.loadtxt)更慢,但换来更高的灵活性——尤其是genfromtxt能够处理缺失数据,而loadtxt这类更快更简单的函数无法做到。
在源码中可以看到这一架构的直接印证:numpy/lib/_npyio_impl.py#L2260-L2283 先逐行split_line(line)得到字符串切片并收集到rows列表,随后在 numpy/lib/_npyio_impl.py#L2336-L2345 通过每个列对应的StringConverter把字符串统一转换为最终类型(_loose_call/_strict_call,对应loose参数)。
定义输入:fname 参数的多种形态
genfromtxt唯一的必选参数是数据来源fname,它可以是:
- 字符串:被当作本地或远程文件的文件名;
- 字符串列表 / 生成器:列表中的每个字符串被视为文件的一行,生成器则要求逐次产出字符串或字节;
- 带
read方法的文件类对象:例如真实文件句柄或io.StringIO对象。
如果传入的是远程文件 URL,文件会被自动下载到当前目录并打开(源码中通过np.lib._datasource.open打开数据源,见 numpy/lib/_npyio_impl.py#L1979-L1986)。此外,fname也接受pathlib.Path对象(源码会先os.fspath转换为字符串)。
可识别的文件类型为文本文件和压缩归档:目前支持gzip与bz2(bzip2)两种归档,归档类型由文件扩展名决定——文件名以'.gz'结尾则按 gzip 解压,以'.bz2'结尾则按 bzip2 解压。
源码中还额外强调:传入的生成器必须返回字节或字符串;若传入对象既不是字符串也不是可迭代对象,会抛出TypeError(提示信息见 numpy/lib/_npyio_impl.py#L1988-L1993)。
把行分割成列
文件打开后,genfromtxt会把每个非空行拆分成字符串序列,空行与注释行直接跳过。分割方式由delimiter、autostrip与comments三个参数共同控制,对应的底层实现是 numpy/lib/_iotools.py#L133-L226 中的LineSplitter类,它在初始化时根据delimiter的类型选择三种分割器之一(见下表)。
delimiter 参数
多数情况下,列与列之间用单个字符分隔。例如逗号分隔的 CSV 文件用,,也有文件用分号;:
>>> data = "1, 2, 3\n4, 5, 6" >>> np.genfromtxt(StringIO(data), delimiter=",") array([[1., 2., 3.], [4., 5., 6.]])另一种常见分隔符是制表符"\t"。但分隔符不限于单个字符——任意字符串都可以作为分隔符。默认情况下delimiter=None,此时行会按空白(含制表符)切分,且连续的多个空白被视为一个空白。
| delimiter 取值 | 底层分割器(LineSplitter) | 行为 |
|---|---|---|
None(默认) | _delimited_splitter | 按连续空白切分 |
| 字符串 | _delimited_splitter | 按该字符串切分(line.split(delimiter)) |
| 单个整数 | _fixedwidth_splitter | 每列固定宽度,slice(i, i+width)逐个切片 |
| 整数序列 | _variablewidth_splitter | 每列宽度不同,用itertools.pairwise生成切片区间 |
当面对固定宽度文件时,需要把delimiter设为单个整数(所有列宽度相同)或整数序列(各列宽度不同):
>>> data = " 1 2 3\n 4 5 67\n890123 4" >>> np.genfromtxt(StringIO(data), delimiter=3) array([[ 1., 2., 3.], [ 4., 5., 67.], [890., 123., 4.]]) >>> data = "123456789\n 4 7 9\n 4567 9" >>> np.genfromtxt(StringIO(data), delimiter=(4, 3, 2)) array([[1234., 567., 89.], [ 4., 7., 9.], [ 4., 567., 9.]])注意固定宽度模式下,源码先按split(comments)[0]切掉注释部分,再按宽度切片,且切片发生在去掉首尾\r\n之后(见 numpy/lib/_iotools.py#L207-L215),因此行尾换行符不会污染最后一列。
autostrip 参数
默认情况下,行被分解为字符串序列后,每个条目不会去除首尾空白。可以通过设置autostrip=True覆盖这一行为:
>>> data = "1, abc , 2\n 3, xxx, 4" >>> # Without autostrip >>> np.genfromtxt(StringIO(data), delimiter=",", dtype="|U5") array([['1', ' abc ', ' 2'], ['3', ' xxx', ' 4']], dtype='<U5') >>> # With autostrip >>> np.genfromtxt(StringIO(data), delimiter=",", dtype="|U5", autostrip=True) array([['1', 'abc', '2'], ['3', 'xxx', '4']], dtype='<U5')从源码看,LineSplitter.autostrip只是用lambda input: [_.strip() for _ in method(input)]包装了底层分割器(numpy/lib/_iotools.py#L149-L167),实现非常简单,但这一行为在后续缺失值识别与自定义转换器中非常关键——官方文档特别提醒:自定义转换器接收的字符串默认未 strip,所以转换函数内部通常需要自行strip()。
comments 参数
comments参数用于定义注释起始标记,默认comments='#'。注释标记可以出现在行内任意位置,其后所有字符都会被忽略:
>>> data = """# ... # Skip me ! ... # Skip me too ! ... 1, 2 ... 3, 4 ... 5, 6 #This is the third line of the data ... 7, 8 ... # And here comes the last line ... 9, 0 ... """ >>> np.genfromtxt(StringIO(data), comments="#", delimiter=",") array([[1., 2.], [3., 4.], [5., 6.], [7., 8.], [9., 0.]])实现上,LineSplitter的三个分割器统一先执行line.split(self.comments)[0]截断注释,再处理数据(numpy/lib/_iotools.py#L198-L205)。
一个值得注意的例外:如果同时设置了names=True,第一条注释行会被检查是否包含列名(见下文“从数据本身读取列名”)。源码中的处理逻辑在 numpy/lib/_npyio_impl.py#L2010-L2016:读取第一行后,若names is True且comments非空,则把comments之后的拼接内容当作候选行。
跳过行与选择列
skip_header 与 skip_footer
文件头部若存在表头等元信息,会妨碍数据处理。此时用skip_header参数——它的值必须是整数,表示在任何其他动作之前跳过文件开头的多少行。类似地,用skip_footer=n跳过文件末尾的 n 行:
>>> data = "\n".join(str(i) for i in range(10)) >>> np.genfromtxt(StringIO(data),) array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) >>> np.genfromtxt(StringIO(data), ... skip_header=3, skip_footer=5) array([3., 4.])默认skip_header=0、skip_footer=0,即不跳过任何行。源码在 numpy/lib/_npyio_impl.py#L2003-L2005 通过循环next(fhd)跳过头部行,并在 numpy/lib/_npyio_impl.py#L2330-L2334 用切片rows[:-skip_footer]截掉尾部行。
兼容性提醒(源码 docstring 明确记载):旧参数skiprows已在 NumPy 1.10 移除,请改用skip_header;missing参数同样在 1.10 移除,请改用missing_values。
usecols
有时我们只关心部分列。usecols参数接受单个整数或整数序列,对应要导入的列索引。按惯例第一列的索引是 0;负整数与 Python 负索引行为一致(源码在 numpy/lib/_npyio_impl.py#L2067-L2068 会把负数current + len(first_values)转换为正索引)。
例如只导入第一列和最后一列,用usecols=(0, -1):
>>> data = "1 2 3\n4 5 6" >>> np.genfromtxt(StringIO(data), usecols=(0, -1)) array([[1., 3.], [4., 6.]])如果列有名字,还可以用列名来选择,既可以是字符串序列,也可以是逗号分隔的字符串:
>>> data = "1 2 3\n4 5 6" >>> np.genfromtxt(StringIO(data), ... names="a, b, c", usecols=("a", "c")) array([(1., 3.), (4., 6.)], dtype=[('a', '<f8'), ('c', '<f8')]) >>> np.genfromtxt(StringIO(data), ... names="a, b, c", usecols=("a, c")) array([(1., 3.), (4., 6.)], dtype=[('a', '<f8'), ('c', '<f8')])源码会把usecols统一规范化为列表,字符串名称通过names.index(current)换算成索引(numpy/lib/_npyio_impl.py#L2062-L2076),同时会同步收缩dtype或names,保证只保留被选中的列。当usecols索引越界时,该行被记为 invalid(numpy/lib/_npyio_impl.py#L2266-L2272),最终按invalid_raise决定报错或告警。
选择数据类型
控制字符串序列如何被转换的主要方式是dtype参数,可接受的值有:
- 单一类型,如
dtype=np.float64:输出为给定类型的二维数组——除非通过names给每列命名(见下文)。注意dtype=np.float64正是genfromtxt的默认值(源码签名dtype=float,见 numpy/lib/_npyio_impl.py#L1735)。 - 类型序列,如
dtype=(np.int_, np.float64, np.float64)。 - 逗号分隔字符串,如
dtype="i4,f8,|U3"。 - 含
'names'与'formats'两个键的字典。 - 元组序列
(name, type),如dtype=[('A', np.int_), ('B', np.float64)]。 - 现成的
numpy.dtype对象。 - 特殊值
None:列类型由数据本身决定(见下文)。
除第一种情况外,输出都是带结构化 dtype 的一维数组,字段数与序列中元素个数一致,字段名由names关键字定义。源码会把所有非None的 dtype 统一交给 numpy/lib/_iotools.py#L824 的easy_dtype归一化为结构化 dtype,并用flatten_dtype(numpy/lib/_iotools.py#L85-L130)把嵌套字段/带形状的字段展开,从而支持嵌套结构化 dtype。
dtype=None 的自动推断
当dtype=None时,每列类型由其数据迭代确定,推断顺序为:
- 先检查能否转换为布尔(字符串是否匹配小写
true/false); - 再检查能否转换为整数;
- 然后是浮点数;
- 接着是复数;
- 最终退回字符串。
源码中每个列由一个StringConverter(None, ...)实例负责,读取全部行后调用converter.iterupgrade(current_column)迭代升级类型(numpy/lib/_npyio_impl.py#L2286-L2300),最后根据各列推断出的类型决定输出是均匀的普通数组还是结构化数组(numpy/lib/_npyio_impl.py#L2349-L2403)。
性能提醒:dtype=None是为方便而提供的选项,但它比显式指定 dtype明显更慢。对性能敏感的大文件,应始终显式给出dtype。
设置列名
处理表格数据时,给每列命名是自然需求。
names 参数
方式一:使用显式结构化 dtype
>>> data = StringIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, dtype=[(_, np.int_) for _ in "abc"]) array([(1, 2, 3), (4, 5, 6)], dtype=[('a', '<i8'), ('b', '<i8'), ('c', '<i8')])方式二:使用 names 关键字(字符串序列或逗号分隔字符串)
>>> data = StringIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, names="A, B, C") array([(1., 2., 3.), (4., 5., 6.)], dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<f8')])上例中默认dtype=np.float64;一旦提供了名字序列,输出就被强制为结构化 dtype。
方式三:从数据本身读取列名——把names设为True,列名从第一行(跳过skip_header行之后的第一行)读取,即使该行是注释行也可以:
>>> data = StringIO("So it goes\n#a b c\n1 2 3\n 4 5 6") >>> np.genfromtxt(data, skip_header=1, names=True) array([(1., 2., 3.), (4., 5., 6.)], dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])覆盖规则:names的默认值是None。只要给了其他任何值,新的名字就会覆盖dtype 中已定义的字段名:
>>> data = StringIO("1 2 3\n 4 5 6") >>> ndtype=[('a', np.int_), ('b', np.float64), ('c', np.int_)] >>> names = ["A", "B", "C"] >>> np.genfromtxt(data, names=names, dtype=ndtype) array([(1, 2., 3), (4, 5., 6)], dtype=[('A', '<i8'), ('B', '<f8'), ('C', '<i8')])从源码看,names=True时名字取自第一条有效行,并经过NameValidator校验(numpy/lib/_npyio_impl.py#L2044-L2046);names为字符串时先split(',')再校验(numpy/lib/_npyio_impl.py#L2047-L2048)。
defaultfmt 参数
如果names=None但仍期望结构化 dtype,字段名会使用 NumPy 标准默认模板"f%i",生成f0、f1……:
>>> data = StringIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, dtype=(np.int_, np.float64, np.int_)) array([(1, 2., 3), (4, 5., 6)], dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<i8')])同理,如果提供的名字数量不足以匹配 dtype 的字段数,缺失的名字也会用该默认模板补齐:
>>> data = StringIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, dtype=(np.int_, np.float64, np.int_), names="a") array([(1, 2., 3), (4, 5., 6)], dtype=[('a', '<i8'), ('f0', '<f8'), ('f1', '<i8')])可以用defaultfmt覆盖这个默认模板,它接受任意格式字符串:
>>> data = StringIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, dtype=(np.int_, np.float64, np.int_), defaultfmt="var_%02i") array([(1, 2., 3), (4, 5., 6)], dtype=[('var_00', '<i8'), ('var_01', '<f8'), ('var_02', '<i8')])需要牢记:defaultfmt只在“期望有名字但未提供”时才会被使用。
名称校验:deletechars / excludelist / case_sensitive
带结构化 dtype 的 NumPy 数组可以被视为numpy.recarray,此时字段可以像属性一样访问(如data.fieldname)。因此字段名必须不含空格或非法字符,也不能与标准属性(如size、shape)重名,否则会干扰解释器。genfromtxt提供三个可选参数精细控制命名,其底层校验器是 numpy/lib/_iotools.py#L229 的NameValidator类:
deletechars:一个字符串,包含所有必须从名字中删除的字符。默认非法字符集为~!@#$%^&*()-=+~\|]}[{';:/?.>,<(源码中来自NameValidator.defaultdeletechars,并在 numpy/lib/_npyio_impl.py#L1739 排序后作为默认值)。excludelist:需要排除的名字列表,如return、file、print等。若输入名命中该列表,会在名字后追加下划线'_'(源码中默认排除列表为['return', 'file', 'print'],用户提供的列表会追加到其后)。case_sensitive:是否区分大小写——case_sensitive=True保持原样;case_sensitive=False或case_sensitive='upper'转为大写;case_sensitive='lower'转为小写。
NameValidator还有一个相关参数replace_space(默认'_'),用于把名字中的空白替换为指定字符(源码签名中位于autostrip之前)。
微调转换:converters
通常定义好dtype就足以确定转换规则,但有时需要更精细的控制。例如,希望把YYYY/MM/DD格式的日期转为datetime.datetime对象,或把xx%这样的字符串转为 0 到 1 之间的浮点数。这时应该用converters参数定义转换函数。
converters的取值通常是字典,键是列索引或列名,值是转换函数;转换函数既可以是普通函数也可以是 lambda 函数。无论如何,它们应当只接受一个字符串作为输入,只输出单个目标类型的元素。
下面的例子把第二列从带%的字符串转换为 0~1 的浮点数:
>>> convertfunc = lambda x: float(x.strip("%"))/100. >>> data = "1, 2.3%, 45.\n6, 78.9%, 0" >>> names = ("i", "p", "n") >>> # General case ..... >>> np.genfromtxt(StringIO(data), delimiter=",", names=names) array([(1., nan, 45.), (6., nan, 0.)], dtype=[('i', '<f8'), ('p', '<f8'), ('n', '<f8')])这里要记住默认dtype=np.float64,第二列期望浮点数,但' 2.3%'与' 78.9%'无法直接转成 float,于是得到np.nan。改用转换器后:
>>> # Converted case ... >>> np.genfromtxt(StringIO(data), delimiter=",", names=names, ... converters={1: convertfunc}) array([(1., 0.023, 45.), (6., 0.789, 0.)], dtype=[('i', '<f8'), ('p', '<f8'), ('n', '<f8')])同样的结果也可以把第二列的名字"p"作为键:
>>> # Using a name for the converter ... >>> np.genfromtxt(StringIO(data), delimiter=",", names=names, ... converters={"p": convertfunc}) array([(1., 0.023, 45.), (6., 0.789, 0.)], dtype=[('i', '<f8'), ('p', '<f8'), ('n', '<f8')])转换器也可以用来为缺失条目提供默认值。下面的convert把去除空白后的字符串转成对应浮点数,空字符串则转成-999。注意必须显式 strip 字符串,因为默认不会去除空白:
>>> data = "1, , 3\n 4, 5, 6" >>> convert = lambda x: float(x.strip() or -999) >>> np.genfromtxt(StringIO(data), delimiter=",", ... converters={1: convert}) array([[ 1., -999., 3.], [ 4., 5., 6.]])源码中对converters的处理要点(numpy/lib/_npyio_impl.py#L2199-L2242):
- 键为字符串时先通过
names.index(j)换算成列索引; - 若同时指定了
usecols,键会按usecols.index(j)重新映射到内部列位置; - 用户转换器通过
converters[i].update(user_conv, locked=True, ...)与默认StringConverter合并——转换器是锁定的,因此在dtype=None时不会在迭代升级中被替换。
测试用例 numpy/lib/tests/test_io.py 中test_converters_with_usecols、test_converters_with_usecols_and_names、test_converters_cornercases等覆盖了转换器与usecols、names组合以及日期/datetime64转换等边界场景。
缺失值与填充值
数据集中可能存在缺失条目。上一节用转换器把空字符串转成浮点数,但自定义转换器管理起来可能很快变得繁琐。genfromtxt为此提供了两个互补机制:missing_values用于识别缺失数据,filling_values用于处理这些缺失数据。
missing_values
默认情况下,任何空字符串都被标记为缺失。我们也可以定义更复杂的字符串(如"N/A"、"???")来表示缺失或无效数据。missing_values接受三种取值:
- 字符串或逗号分隔字符串:作为所有列的缺失标记;
- 字符串序列:按顺序与各列一一对应;
- 字典:值为字符串或字符串序列,键可以是列索引(整数)或列名(字符串);此外,特殊键
None可用于定义适用于所有列的默认标记。
源码实现(numpy/lib/_npyio_impl.py#L2087-L2133)先为每列初始化[['']](即默认空串缺失),再根据用户输入形态逐列扩展标记列表。
filling_values
识别出缺失数据后,还需要为缺失条目提供值。默认值由期望 dtype 决定,对应关系如下表:
| 期望类型 | 默认填充值 |
|---|---|
bool | False |
int | -1 |
float | np.nan |
complex | np.nan+0j |
string | '???' |
filling_values提供更精细的控制,同样接受三种取值:
- 单个值:作为所有列的默认填充值;
- 值序列:每一项作为对应列的默认值;
- 字典:键为列索引或列名,值为单个对象;同样可用特殊键
None定义所有列的默认值。
下面综合示例中,第一列以"N/A"标记缺失、第三列以"???"标记缺失,同时把第一、二列的缺失值替换为 0,最后一列的缺失值替换为-999:
>>> data = "N/A, 2, 3\n4, ,???" >>> kwargs = dict(delimiter=",", ... dtype=np.int_, ... names="a,b,c", ... missing_values={0:"N/A", 'b':" ", 2:"???"}, ... filling_values={0:0, 'b':0, 2:-999}) >>> np.genfromtxt(StringIO(data), **kwargs) array([(0, 2, 3), (4, 0, -999)], dtype=[('a', '<i8'), ('b', '<i8'), ('c', '<i8')])注意上例中第二列用列名'b'而其余用索引,且'b'的缺失标记是空格" "(源码在 numpy/lib/_npyio_impl.py#L2090-L2118 会把字符串键通过names.index换算成索引)。
usemask:追踪缺失位置
有时需要保留缺失数据发生位置的记录——构造一个布尔掩码,缺失处为True、否则为False。只需把usemask设为True(默认False),输出数组就会变成numpy.ma.MaskedArray。
源码中当usemask=True时,逐行记录masks(numpy/lib/_npyio_impl.py#L2278-L2281),最后用掩码构造MaskedArray并挂接_mask(numpy/lib/_npyio_impl.py#L2472-L2474)。此外,即使某些缺失值已被填充掉,源码还会在 numpy/lib/_npyio_impl.py#L2463-L2470 通过output[name] == mval二次比对,把与缺失标记等值的输出也标记为掩码,确保掩码完整反映原始缺失情况。
更多实用参数与边界行为
除了上述核心参数,genfromtxt的完整签名(numpy/lib/_npyio_impl.py#L1735-L1743)还包含若干常用控制项:
loose(默认True):True时对无效值不抛错(转为nan等);False时使用_strict_call严格转换。invalid_raise(默认True):检测到列数不一致时,True抛出ValueError,False则发出ConversionWarning告警并跳过问题行。错误信息形如Line #N (got M columns instead of K)(numpy/lib/_npyio_impl.py#L2302-L2328)。max_rows:最多读取的行数,必须 ≥ 1;不能与skip_footer同时使用,否则抛ValueError(numpy/lib/_npyio_impl.py#L1954-L1960)。encoding:输入文件解码使用的编码,对文件对象不适用。NumPy 2.0 起默认值由'bytes'改为None(使用系统默认编码);特殊值'bytes'保留旧版行为(尽量返回字节数组、以 latin1 传给转换器),未指定编码读取 unicode 字符串会触发VisibleDeprecationWarning(numpy/lib/_npyio_impl.py#L2356-L2362)。ndmin(1.23 新增):与loadtxt相同的维度控制;unpack:True时返回转置结果,可配合x, y, z = genfromtxt(...)解包,结构化 dtype 时按字段分别返回数组(numpy/lib/_npyio_impl.py#L2478-L2487);like(1.20 新增):支持数组 API 风格的__array_function__协议。
还有三个官方文档明确记载的使用注意点:
- 使用空白作为分隔符(或未指定
delimiter)时,两个字段之间不应存在缺失数据; - 当变量被命名(结构化 dtype 或
names序列)时,文件里不应再有表头,否则会抛出ValueError; - 单个值默认不做空白剥离,使用自定义转换器时要确保函数内部去除空白;且由于 dtype 推断机制,自定义转换器可能收到意料之外的值。
总结与选型建议
numpy.genfromtxt用双循环换来高灵活性:delimiter(单字符/任意字符串/固定宽度)解决行分割,dtype与converters控制类型转换,names/defaultfmt/NameValidator家族管理列名,missing_values/filling_values/usemask三件套处理缺失数据,skip_header/skip_footer/usecols完成行与列的裁剪。
日常选型的务实建议:
- 数据规整、无缺失时,优先使用更快的
numpy.loadtxt; - 需要容忍缺失值、异构类型或自定义列名时,使用
genfromtxt,并尽量显式指定dtype(dtype=None的自动推断较慢); - 需要记录缺失位置时打开
usemask=True,配合MaskedArray继续下游分析; - 处理大文件时注意
max_rows限制读取量,并留意encoding参数在 NumPy 2.x 下的默认值变化。
更多官方文档与源码入口:用户指南原文见 doc/source/user/basics.io.genfromtxt.rst,函数实现见 numpy/lib/_npyio_impl.py#L1735-L2488,底层工具类(LineSplitter、NameValidator、StringConverter、easy_dtype、flatten_dtype)见 numpy/lib/_iotools.py,完整的测试覆盖见 numpy/lib/tests/test_io.py。
- 科学计算
- 数据分析
【免费下载链接】numpy
The fundamental package for scientific computing with Python.
相关推荐
NumPy 掩码数组(numpy.ma)完全指南:缺失值与无效数据的处理机制
NumPy 掩码数组(numpy.ma)完全指南:缺失值与无效数据的处理机制 导读 本文以 NumPy 官方参考文档 doc/source/reference/
科学计算数据分析MXNet numpy 模块的输入输出(I/O)与文本格式化指南:genfromtxt、ndarray.tolist 与 set_printoptions 详解
MXNet numpy 模块的输入输出(I/O)与文本格式化指南:genfromtxt、ndarray.tolist 与 set_printoptions 详解
人工智能深度学习机器学习Handsontable数据导入导出:Excel、CSV文件处理完全指南
Handsontable数据导入导出:Excel、CSV文件处理完全指南 Handsontable是一款功能强大的JavaScript电子表格组件,提供了完善的
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考