genfromtxt
的惟一强制参数是数据的源。它能够是字符串,字符串列表或生成器。若是提供了单个字符串,则假定它是本地或远程文件或具备read
方法的打开的类文件对象的名称,例如文件或StringIO.StringIO
对象。若是提供了字符串列表或返回字符串的生成器,则每一个字符串在文件中被视为一行。当传递远程文件的URL时,文件将自动下载到当前目录并打开。 python
识别的文件类型是文本文件和归档。目前,该函数识别gzip
和bz2
(bzip2)归档。归档的类型从文件的扩展名肯定:若是文件名以'.gz'
结尾,则须要一个gzip
归档;若是以'bz2'
结尾,则假设存在一个bzip2
档案。数组
一旦文件被定义并打开阅读,genfromtxt
将每一个非空行拆分为一个字符串序列。刚刚跳过空行或注释行。delimiter
关键字用于定义拆分应如何进行。函数
一般,单个字符标记列之间的间隔。例如,逗号分隔文件(CSV)使用逗号(,
)或分号(;
)做为分隔符:spa
import numpy as np from io import BytesIO data = b"1, 2, 3\n4, 5, 6" np.genfromtxt(BytesIO(data), delimiter=",") Out[334]: array([[1., 2., 3.], [4., 5., 6.]])
另外一个常见的分隔符是"\t"
,表格字符。可是,咱们不限于单个字符,任何字符串都会作。默认状况下,genfromtxt
假定delimiter=None
,表示该行沿白色空格(包括制表符)分割,而且连续的空格被视为单个白色空格。code
或者,咱们可能处理固定宽度的文件,其中列被定义为给定数量的字符。在这种状况下,咱们须要将delimiter
设置为单个整数(若是全部列具备相同的大小)或整数序列(若是列能够具备不一样的大小):orm
data = b"1, 2, 3\n4, 5, 6" np.genfromtxt(BytesIO(data), delimiter=",") Out[334]: array([[1., 2., 3.], [4., 5., 6.]]) data = b" 1 2 3\n 4 5 67\n890123 4" np.genfromtxt(BytesIO(data), delimiter=3) Out[336]: array([[ 1., 2., 3.], [ 4., 5., 67.], [890., 123., 4.]]) data = B"123456789\n 4 7 9\n 4567 9" np.genfromtxt(BytesIO(data), delimiter=(4, 3, 2)) Out[338]: array([[1234., 567., 89.], [ 4., 7., 9.], [ 4., 567., 9.]])
默认状况下,当一行被分解为一系列字符串时,各个条目不会被删除前导或尾随的空格。经过将可选参数autostrip
设置为True
的值,能够覆盖此行为:对象
data = b"1, abc , 2\n 3, xxx, 4" np.genfromtxt(BytesIO(data), delimiter=",", dtype="|S5") Out[340]: array([[b'1', b' abc ', b' 2'], [b'3', b' xxx', b' 4']], dtype='|S5') np.genfromtxt(BytesIO(data), delimiter=",", dtype="|S5", autostrip=True) Out[341]: array([[b'1', b'abc', b'2'], [b'3', b'xxx', b'4']], dtype='|S5')
omments参数blog
可选参数comments
用于定义标记注释开始的字符串。默认状况下,genfromtxt
假设为comments='#'
。注释标记能够出如今该行的任何地方。忽略注释标记后的任何字符:索引
data = b"""# # 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(BytesIO(data), comments="#", delimiter=",") Out[345]: array([[1., 2.], [3., 4.], [5., 6.], [7., 8.], [9., 0.]])
注意ip
这种行为有一个显着的例外:若是可选参数names=True
,则将首先检查第一条注释的行的名称。
文件中头的存在可能阻碍数据处理。在这种状况下,咱们须要使用skip_header
可选参数。此参数的值必须是对应于在执行任何其余操做以前在文件开头处跳过的行数的整数。相似地,咱们可使用skip_footer
属性并赋予n
的值来跳过文件的最后n
行:
>>> data = "\n".join(str(i) for i in range(10)) >>> np.genfromtxt(BytesIO(data),) array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) >>> np.genfromtxt(BytesIO(data), ... skip_header=3, skip_footer=5) array([ 3., 4.])
默认状况下,skip_header=0
和skip_footer=0
,表示不跳过任何行。
在某些状况下,咱们对数据的全部列不感兴趣,但只对其中的几个列感兴趣。咱们可使用usecols
参数选择要导入哪些列。此参数接受单个整数或对应于要导入的列的索引的整数序列。记住,按照惯例,第一列的索引为0。负整数的行为与常规Python负指数相同。
例如,若是咱们只想导入第一列和最后一列,可使用usecols =(0, -1)
:
>>> data = "1 2 3\n4 5 6" >>> np.genfromtxt(BytesIO(data), usecols=(0, -1)) array([[ 1., 3.], [ 4., 6.]])
若是列具备名称,咱们还能够经过将其名称做为字符串序列或逗号分隔字符串的形式,将其名称指定给usecols
参数来选择要导入的列:
>>> data = "1 2 3\n4 5 6" >>> np.genfromtxt(BytesIO(data), ... names="a, b, c", usecols=("a", "c")) array([(1.0, 3.0), (4.0, 6.0)], dtype=[('a', '<f8'), ('c', '<f8')]) >>> np.genfromtxt(BytesIO(data), ... names="a, b, c", usecols=("a, c")) array([(1.0, 3.0), (4.0, 6.0)], dtype=[('a', '<f8'), ('c', '<f8')])
控制如何将从文件中读取的字符串序列转换为其余类型的主要方法是设置dtype
参数。此参数的可接受值为:
单个类型,例如dtype=float
。除非已使用names
参数将名称与每一个列相关联(参见下文),不然输出将为具备给定dtype的2D。请注意,dtype=float
是genfromtxt
的默认值。
类型序列,例如dtype =(int, float, float)
。
逗号分隔的字符串,例如dtype="i4,f8,|S3"
。
具备两个键'names'
和'formats'
的字典。
元组的序列(名称, 类型)
,例如dtype = [('A', t4 > int), ('B', float)]
。
现有的numpy.dtype
对象。
特殊值None
。在这种状况下,列的类型将从数据自己肯定(见下文)。
在全部状况下,但第一个,输出将是具备结构化dtype的1D数组。此dtype具备与序列中的项目同样多的字段。字段名称使用names
关键字定义。
当dtype=None
时,每一个列的类型从其数据中迭代肯定。咱们首先检查字符串是否能够转换为布尔值(即,若是字符串在小写字符串中匹配true
或false
);那么它是否能够转换为整数,而后到一个float,而后到一个复杂,最终到一个字符串。能够经过修改StringConverter
类的默认映射器来更改此行为。
为方便起见,提供了选项dtype=None
。可是,它明显慢于明确设置dtype。
处理表格数据时的一种天然方法是为每一个列分配一个名称。第一种可能性是使用显式结构化dtype,如前所述:
>>> data = BytesIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, dtype=[(_, int) for _ in "abc"]) array([(1, 2, 3), (4, 5, 6)], dtype=[('a', '<i8'), ('b', '<i8'), ('c', '<i8')])
另外一个更简单的可能性是使用names
关键字与一系列字符串或逗号分隔的字符串:
>>> data = BytesIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, names="A, B, C") array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)], dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
在上面的示例中,咱们使用了默认状况下,dtype=float
的事实。经过给出一系列名称,咱们将输出强制为结构化的dtype。
咱们有时可能须要从数据自己定义列名称。在这种状况下,咱们必须使用值True
的names
关键字。而后将从第一行(在skip_header
以后)读取名称,即便行被注释掉:
>>> data = BytesIO("So it goes\n#a b c\n1 2 3\n 4 5 6") >>> np.genfromtxt(data, skip_header=1, names=True) array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)], dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
names
的默认值为None
。若是咱们为关键字赋予任何其余值,新名称将覆盖咱们可能已使用dtype定义的字段名称:
>>> data = BytesIO("1 2 3\n 4 5 6") >>> ndtype=[('a',int), ('b', float), ('c', int)] >>> names = ["A", "B", "C"] >>> np.genfromtxt(data, names=names, dtype=ndtype) array([(1, 2.0, 3), (4, 5.0, 6)], dtype=[('A', '<i8'), ('B', '<f8'), ('C', '<i8')])
If names=None
but a structured dtype is expected, names are defined with the standard NumPy default of "f%i"
, yielding names like f0
, f1
and so forth:
>>> data = BytesIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, dtype=(int, float, int)) array([(1, 2.0, 3), (4, 5.0, 6)], dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<i8')])
一样,若是咱们没有给出足够的名称来匹配dtype的长度,那么将使用此默认模板定义缺乏的名称:
>>> data = BytesIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, dtype=(int, float, int), names="a") array([(1, 2.0, 3), (4, 5.0, 6)], dtype=[('a', '<i8'), ('f0', '<f8'), ('f1', '<i8')])
咱们可使用defaultfmt
参数覆盖此默认值,它采用任何格式字符串:
>>> data = BytesIO("1 2 3\n 4 5 6") >>> np.genfromtxt(data, dtype=(int, float, int), defaultfmt="var_%02i") array([(1, 2.0, 3), (4, 5.0, 6)], dtype=[('var_00', '<i8'), ('var_01', '<f8'), ('var_02', '<i8')])
注意
咱们须要记住,defaultfmt
仅在预期某些名称但未定义时使用。
具备结构化dtype的NumPy数组也能够视为recarray
,其中能够像访问属性同样访问字段。所以,咱们可能须要确保字段名称不包含任何空格或无效字符,或者不符合标准属性的名称(例如size
或shape
),这将会混淆解释器。genfromtxt
接受三个可选参数,对名称提供更精细的控制:
deletechars
提供一个字符串,组合必须从名称中删除的全部字符。默认状况下,无效字符为〜!@#$%^&amp; *() - = +〜\ |]} [{';: /?.& &lt;
。
excludelist
提供要排除的名称列表,例如return
,file
,print
...若是输入名称之一是此列表的一部分,将在其后面添加下划线字符('_'
)。
case_sensitive
是否名称应区分大小写(case_sensitive=True
),转换为大写(case_sensitive=False
或case_sensitive='upper'
)或小写(case_sensitive='lower'
)。
一般,定义一个dtype足以定义如何转换字符串序列。然而,有时可能须要一些额外的控制。例如,咱们可能要确保格式YYYY/MM/DD
的日期被转换为datetime
对象,或者像xx%
已正确转换为0到1之间的浮点值。在这种状况下,咱们应该使用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(BytesIO(data), delimiter=",", names=names) array([(1.0, nan, 45.0), (6.0, nan, 0.0)], dtype=[('i', '<f8'), ('p', '<f8'), ('n', '<f8')])
咱们须要记住,默认状况下,dtype=float
。所以,对于第二列指望浮点数。可是,字符串'2.3%'
和' 78.9% >
没法转换为浮点数,咱们最终改成使用np.nan
。让咱们如今使用转换器:
>>> # Converted case ... >>> np.genfromtxt(BytesIO(data), delimiter=",", names=names, ... converters={1: convertfunc}) array([(1.0, 0.023, 45.0), (6.0, 0.78900000000000003, 0.0)], dtype=[('i', '<f8'), ('p', '<f8'), ('n', '<f8')])
使用第二列的名称("p"
)做为键而不是索引(1)能够得到相同的结果:
>>> # Using a name for the converter ... >>> np.genfromtxt(BytesIO(data), delimiter=",", names=names, ... converters={"p": convertfunc}) array([(1.0, 0.023, 45.0), (6.0, 0.78900000000000003, 0.0)], dtype=[('i', '<f8'), ('p', '<f8'), ('n', '<f8')])
转换器还可用于为缺乏的条目提供默认值。在如下示例中,转换器convert
将剥离的字符串转换为相应的浮点型或若是字符串为空,转换为-999。咱们须要从空格中显式删除字符串,由于它不是默认作的:
>>> data = "1, , 3\n 4, 5, 6" >>> convert = lambda x: float(x.strip() or -999) >>> np.genfromtxt(BytesIO(data), delimiter=",", ... converters={1: convert}) array([[ 1., -999., 3.], [ 4., 5., 6.]])
在咱们尝试导入的数据集中可能会丢失某些条目。在前面的示例中,咱们使用转换器将空字符串转换为浮点数。然而,用户定义的转换器可能迅速地变得难以管理。
genfromtxt
函数提供了另外两个补充机制:missing_values
参数用于识别丢失的数据,第二个参数filling_values
这些丢失的数据。
默认状况下,任何空字符串都标记为缺乏。咱们还能够考虑更复杂的字符串,例如"N/A"
或"???"
以表示丢失或无效的数据。missing_values
参数接受三种类型的值:
一个字符串或逗号分隔的字符串
此字符串将用做全部列的缺乏数据的标记
字符串序列
在这种状况下,每一个项目按顺序与列相关联。
一本字典
字典的值是字符串或字符串序列。相应的键能够是列索引(整数)或列名(字符串)。此外,特殊键None
可用于定义适用于全部列的默认值。
咱们知道如何识别丢失的数据,但咱们仍然须要为这些丢失的条目提供一个值。默认状况下,此值根据此表从预期的dtype肯定:
预期类型
默认
|
|
|
|
|
|
|
|
|
|
咱们可使用filling_values
可选参数对缺失值的转换进行更精细的控制。像missing_values
同样,此参数接受不一样类型的值:
单个值
这将是全部列的默认值
一个值序列
每一个条目将是相应列的默认值
一本字典
每一个键能够是列索引或列名,而且相应的值应该是单个对象。咱们可使用特殊键None
为全部列定义默认值。
在下面的例子中,咱们假设缺乏的值在第一列中用"N/A"
标记,"???"
在第三列。咱们但愿将这些缺失值转换为0,若是它们出如今第一列和第二列中,则转换为-999,若是它们出如今最后一列中:
>>> data = "N/A, 2, 3\n4, ,???" >>> kwargs = dict(delimiter=",", ... dtype=int, ... names="a,b,c", ... missing_values={0:"N/A", 'b':" ", 2:"???"}, ... filling_values={0:0, 'b':0, 2:-999}) >>> np.genfromtxt(BytesIO(data), **kwargs) array([(0, 2, 3), (4, 0, -999)], dtype=[('a', '<i8'), ('b', '<i8'), ('c', '<i8')])
咱们还可能但愿经过构造布尔掩码来跟踪丢失数据的出现,其中缺乏数据的True
条目,不然False
。为此,咱们只须要将可选参数usemask
设置为True
(默认值为False
)。输出数组将是MaskedArray
。
除了genfromtxt
,numpy.lib.io
模块提供了从genfromtxt
派生的几个方便函数。这些函数的工做方式与原始函数相同,但它们具备不一样的默认值。
ndfromtxt
usemask=False
。输出始终为标准numpy.ndarray
。mafromtxt
usemask=True
。输出始终为MaskedArray
recfromtxt
numpy.recarray
(if usemask=False
)或MaskedRecords
数组(若是usemaske=True
。默认dtype为dtype=None
,表示每一个列的类型将自动肯定。recfromcsv
recfromtxt
,但使用默认的delimiter=","
。