【Numpy基础知识】使用genfromtxt导入数据

news2025/6/15 2:30:22

使用Numpy进行I/O操作

来源:Numpy官网:https://numpy.org/doc/stable/user/basics.html

在这里插入图片描述

文章目录

    • 使用Numpy进行I/O操作
        • 导包
        • 【1】定义输入
        • 【2】将行拆分为列
        • 【3】跳过行和选择列
        • 【4】选择数据类型
        • 【5】设置名称
        • 【6】调整转换
        • 【7】快捷键功能

NumPy 提供了几个函数来从表格数据创建数组。我们在这里专注于 genfromtxt 函数。

导包

import numpy as np
from io import StringIO

【1】定义输入

genfromtxt的唯一强制性参数是数据的来源。它可以是字符串、字符串列表、生成器或具有read方法的打开文件类对象,例如文件或 io.StringIO对象。如果提供了单个字符串,则假定它是本地或远程文件的名称。如果提供了字符串列表或返回字符串的生成器,则每个字符串将被视为文件中的一行。传递远程文件的 URL 时,该文件会自动下载到当前目录并打开。

可识别的文件类型是文本文件和存档。目前,该函数可识别 gzip 和 bz2) 存档。bzip2存档的类型由文件的扩展名确定:如果文件名以’.gz’结尾,则需要 gzip 存档;如果它以’bz2’结尾,则假定为 bzip2 存档。

【2】将行拆分为列

① delimiter 参数

delimiter关键字用于定义拆分应如何进行。

data = u"1,2,3\n4,5,6"
print(data)
1,2,3
4,5,6
print(np.genfromtxt(StringIO(data), delimiter=','))
[[1. 2. 3.]
 [4. 5. 6.]]

另一个常见的分隔符是"\t",即制表字符。但是,我们不限于单个字符,任何字符串都可以。默认情况下,genfromtxt 假定 delimiter=None,这意味着该行沿空格(包括制表符)拆分,并且连续的空格被视为单个空格。

或者,我们可以处理一个固定宽度的文件,其中列被定义为给定数量的字符。在这种情况下,我们需要将delimiter设置为单个整数(如果所有列的大小相同)或整数序列(如果列可以具有不同的大小):

data = u"  1  2  3\n  4  5 67\n890123  4"
print(data)
  1  2  3
  4  5 67
890123  4
print(np.genfromtxt(StringIO(data), delimiter=3))
[[  1.   2.   3.]
 [  4.   5.  67.]
 [890. 123.   4.]]
data = u"123456789\n   4  7 9\n   4567 9"
print(data)
123456789
   4  7 9
   4567 9
print(np.genfromtxt(StringIO(data), delimiter=(4, 3, 2)))
[[1234.  567.   89.]
 [   4.    7.    9.]
 [   4.  567.    9.]]

② autostrip参数

默认情况下,当一行分解为一系列字符串时,各个条目不会去除前导空格或尾随空格。可以通过将可选参数autostrip设置为值 True 来覆盖此行为:

data = u"1, abc , 2\n 3, xxx, 4"
print(data)
1, abc , 2
 3, xxx, 4
# 没有autostrip
print(np.genfromtxt(StringIO(data), delimiter=',', dtype="|U5"))
[['1' ' abc ' ' 2']
 ['3' ' xxx' ' 4']]

可以看到这样转来有空格“不干净”

# 用上autostrip
print(np.genfromtxt(StringIO(data), delimiter=',', dtype="|U5", autostrip=True))
[['1' 'abc' '2']
 ['3' 'xxx' '4']]

这样看起来好多了

③ comments参数

可选参数comments用于定义标记注释开头的字符串。默认情况下,genfromtxt 假定 comments=’#’。注释标记可能出现在行中的任何位置。注释标记后出现的任何字符都将被忽略:

data = u"""#
# 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
"""
print(np.genfromtxt(StringIO(data), comments="#", delimiter=','))
[[1. 2.]
 [3. 4.]
 [5. 6.]
 [7. 8.]
 [9. 0.]]

【注意】版本 1.7.0 中的新功能: 当注释设置为None时,不会将任何行视为comments。

【3】跳过行和选择列

① skip_header和skip_footer

文件中存在标头可能会阻碍数据处理。在这种情况下,我们需要使用 skip_header 可选参数。此参数的值必须是一个整数,对应于在执行任何其他操作之前要在文件开头跳过的行数。同样,我们可以通过使用 skip_footer 属性并为其指定值 n 来跳过文件的最后 n 行

data = u"\n".join(str(i) for i in range(10))
print(data)
0
1
2
3
4
5
6
7
8
9
print(np.genfromtxt(StringIO(data), ))
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]

默认情况下,skip_header=0 和 skip_footer=0,这意味着不会跳过任何行。

print(np.genfromtxt(StringIO(data), skip_header=3, skip_footer=5))
[3. 4.]

② usecols 参数

在某些情况下,我们不是对数据的所有列都感兴趣,而只对其中的几列感兴趣。

例如,如果我们只想导入第一列和最后一列,我们可以使用 usecols=(0, -1):

data = u"1 2 3\n4 5 6"
print(data)
1 2 3
4 5 6
print(np.genfromtxt(StringIO(data), usecols=(0, -1)))
[[1. 3.]
 [4. 6.]]

如果列有名称,我们还可以通过为 usecols 参数命名来选择要导入的列

data = u"1 2 3\n4 5 6"
print(data)
1 2 3
4 5 6
print(np.genfromtxt(StringIO(data), names="a,b,c", usecols=("a", "c")))
[(1., 3.) (4., 6.)]
print(np.genfromtxt(StringIO(data), names="a,b,c", usecols=("a,c")))
[(1., 3.) (4., 6.)]

【4】选择数据类型

控制如何将我们从文件中读取的字符串序列转换为其他类型的主要方法是设置 dtype 参数。此参数的可接受值为:

  • 单个类型,例如 dtype=float。
  • 类型序列,例如 dtype=(int, float, float).
  • 逗号分隔的字符串,例如 dtype=“i4,f8,|U3”.
  • 具有两个键’names’”和’formats’的字典.
  • 元组序列((name, type)例如 dtype=[(‘A’, int), (‘B’, float)].
  • 现有的 numpy.dtype 对象。
  • 特殊值 None。在这种情况下,列的类型将由数据本身确定

【5】设置名称

① names 参数

处理表格数据时的一种自然方法是为每列分配一个名称。

data = StringIO("1 2 3\n 4 5 6")
print(data)
<_io.StringIO object at 0x00000217D2591310>
print(np.genfromtxt(data, dtype=[(_, int) for _ in "abc"]))
[(1, 2, 3) (4, 5, 6)]
print(np.genfromtxt(data, dtype=[(_, int) for _ in "abc"]).dtype)
[('a', '<i4'), ('b', '<i4'), ('c', '<i4')]


C:\Users\DingJiaxiong\AppData\Local\Temp\ipykernel_6888\903119735.py:1: UserWarning: genfromtxt: Empty input file: "<_io.StringIO object at 0x00000217D2591310>"
  print(np.genfromtxt(data, dtype=[(_, int) for _ in "abc"]).dtype)

另一种更简单的方法是将 names 关键字与一系列字符串或逗号分隔的字符串一起使用:

data = StringIO("1 2 3\n 4 5 6")
print(data)
<_io.StringIO object at 0x00000217D2591550>
print(np.genfromtxt(data, names="A,B,C"))
[(1., 2., 3.) (4., 5., 6.)]
print(np.genfromtxt(data, names="A,B,C").dtype)
[('A', '<f8'), ('B', '<f8'), ('C', '<f8')]


C:\Users\DingJiaxiong\AppData\Local\Temp\ipykernel_6888\3894872847.py:1: UserWarning: genfromtxt: Empty input file: "<_io.StringIO object at 0x00000217D2591550>"
  print(np.genfromtxt(data, names="A,B,C").dtype)

我们有时可能需要从数据本身定义列名。【使用值为 True 的 names 关键字。】

data = StringIO("So it goes\n#a b c\n1 2 3\n 4 5 6")
print(np.genfromtxt(data, skip_header=1, names=True))
[(1., 2., 3.) (4., 5., 6.)]

names的默认值为None。如果我们为关键字提供任何其他值,新名称将覆盖我们可能使用 dtype 定义的字段名称:

data = StringIO("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., 3), (4, 5., 6)],
      dtype=[('A', '<i4'), ('B', '<f8'), ('C', '<i4')])

② defaultfmt 参数

如果 names=None 但需要结构化 dtype,则使用标准 NumPy 默认值"f%i"定义名称,生成 f0、f1 等名称

data = StringIO("1 2 3\n 4 5 6")
np.genfromtxt(data, dtype=(int, float, int))
array([(1, 2., 3), (4, 5., 6)],
      dtype=[('f0', '<i4'), ('f1', '<f8'), ('f2', '<i4')])

同样,如果我们没有给出足够的名称来匹配 dtype 的长度,则缺少的名称将使用此默认模板进行定义:

data = StringIO("1 2 3\n 4 5 6")
np.genfromtxt(data, dtype=(int, float, int), names="a")
array([(1, 2., 3), (4, 5., 6)],
      dtype=[('a', '<i4'), ('f0', '<f8'), ('f1', '<i4')])

我们可以用 defaultfmt 参数覆盖这个默认值,该参数采用任何格式字符串:

data = StringIO("1 2 3\n 4 5 6")
np.genfromtxt(data, dtype=(int, float, int), defaultfmt="var_%02i")
array([(1, 2., 3), (4, 5., 6)],
      dtype=[('var_00', '<i4'), ('var_01', '<f8'), ('var_02', '<i4')])

需要记住,defaultfmt 仅在预期但未定义某些名称时使用。

③ 验证名称

具有结构化 dtype 的 NumPy 数组也可以被视为 recarray,其中字段可以像属性一样访问。出于这个原因,我们可能需要确保字段名称不包含任何空格或无效字符,或者它与标准属性的名称(如size或shape)不对应,这会混淆解释器。genfromtxt 接受三个可选参数,这些参数提供了对名称的更精细控制:

  • deletechars
    提供一个字符串,其中包含必须从名称中删除的所有字符。默认情况下,无效字符是!@#$%^&*()-=+|]}[{’;: /?.>,<.

  • excludelist
    给出要排除的名称列表,例如return、file、print…如果其中一个输入名称是此列表的一部分,则会在其后附加下划线字符 (’’_’)。

  • case_sensitive
    名称是否应区分大小写 (case_sensitive=True)、转换为大写 (case_sensitive=False 或 case_sensitive=‘upper’) 或小写 (case_sensitive='upper’case_sensitive=‘lower’).

【6】调整转换

① converters 参数

通常,定义 dtype 足以定义必须如何转换字符串序列。但是,有时可能需要一些额外的控制。例如,我们可能希望确保将YYYY/MM/DD 的日期转换为datetime对象,或者将 xx% 等字符串正确转换为介于 0 和 1 之间的浮点数。在这种情况下,我们应该使用 converters 参数定义转换函数。

在下面的示例中,第二列从表示百分比的字符串转换为介于 0 和 1 之间的浮点数:

convertfunc = lambda x: float(x.strip(b"%")) / 100.
print(convertfunc)
<function <lambda> at 0x00000217D25AF9D0>
data = u"1, 2.3%, 45.\n6, 78.9%, 0"
print(data)
1, 2.3%, 45.
6, 78.9%, 0
names = ("i", "p", "n")
np.genfromtxt(StringIO(data), delimiter=",", names=names)
array([(1., nan, 45.), (6., nan,  0.)],
      dtype=[('i', '<f8'), ('p', '<f8'), ('n', '<f8')])

默认情况下,dtype=float。因此,预计第二列会出现浮点数。但是,字符串 ’ ’ 2.3%’’ 和 ‘’ 78.9%’ 无法转换为浮点数,我们最终得到了 np.nan。现在让我们使用转换器:

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” 作为键而不是其索引 (1),可以获得相同的结果:

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。我们需要从空格中显式去除字符串,因为默认情况下不会这样做:

data = u"1, , 3\n 4, 5, 6"
print(data)
1, , 3
 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.]])

② 使用缺失值和填充值

我们尝试导入的数据集中可能缺少某些条目。在前面的示例中,我们使用转换器将空字符串转换为浮点数。但是,用户定义的转换器可能会很快变得难以管理。

genfromtxt 函数提供了另外两种补充机制:missing_values参数用于识别缺失的数据,第二个参数 filling_values 用于处理这些缺失的数据。

1 missing_values

默认情况下,任何空字符串都标记为缺失。我们还可以考虑更复杂的字符串,例如““N/A"或”???"来表示丢失或无效的数据。missing_values参数接受三种类型的值:

  • 字符串或逗号分隔的字符串
    此字符串将用作所有列缺少数据的标记
  • 字符串序列
    在这种情况下,每个项目都按顺序关联到一列。
  • 字典
    字典的值是字符串或字符串序列。相应的键可以是列索引(整数)或列名(字符串)。此外,特殊键 None 可用于定义适用于所有列的默认值。

2 filling_values

我们知道如何识别缺失的数据,但我们仍然需要为这些缺失的条目提供一个值。默认情况下,此值是根据下表从预期的 dtype 确定的:

我们可以使用filling_values可选参数更精细地控制缺失值的转换。与missing_values一样,此参数接受不同类型的值:

  • 单个值
    这将是所有列的默认值

  • 值序列
    每个条目将是对应列的默认值

  • 字典
    每个键可以是列索引或列名,对应的值应该是单个对象。我们可以使用特殊键 None 为所有列定义默认值。

在下面的示例中,我们假设缺失值在第一列中标记为““N/A”,在第三列中用"???"标记。如果这些缺失值出现在第一列和第二列中,我们希望将它们转换为 0,如果它们出现在最后一列中,我们希望将其转换为 -999:

data = u"N/A, 2, 3\n4, ,???"
print(data)
N/A, 2, 3
4, ,???
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(StringIO(data), **kwargs)
array([(0, 2,    3), (4, 0, -999)],
      dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<i4')])

3 usemask

我们可能还希望通过构造布尔掩码来跟踪丢失数据的发生,在缺少数据的地方使用 True 条目,否则使用 False 条目。为此,我们只需要将可选参数 usemask 设置为 True(默认值为 False)。然后,输出数组将是一个MaskedArray.

【7】快捷键功能

除了 genfromtxt 之外,numpy.lib.npyio 模块还提供了几个从 genfromtxt 派生的便捷函数。这些函数的工作方式与原始函数相同,但它们具有不同的默认值。

numpy.lib.npyio.recfromtxt
返回标准 numpy.recarray (if usemask=False) 或 numpy.ma.mrecords.MaskedRecords 数组(if usemaske=True)。usemask=False默认的 dtype 为 dtype=None,这意味着将自动确定每列的类型。

numpy.lib.npyio.recfromcsv
像numpy.lib.npyio.recfromtxt,但使用默认delimiter=",".

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/104605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA面试(不同类型的公司特点)

工作那么多年面试过很多公司&#xff0c;同时也面试过很多求职者。作为一个JAVA程序员&#xff0c;10年风雨路&#xff0c;10年技术路&#xff0c;一路走来&#xff0c;实属不易&#xff0c;JAVA语言从诞生&#xff0c;到发展起来&#xff0c;到风靡全球&#xff0c;到如今的混…

java回顾:私服搭建

目录 一、搭建私服 1.1、搭建私服原因 1.2、nexus软件的安装 1.3、私服的使用 1.4、仓库介绍 1.5、从私服下载资源 1.6、下载失败 1.7、将资源上传到私服 1.7.1 问题 一、搭建私服 1.1、搭建私服原因 公司开发了jar包&#xff0c;可供其他项目组使用、无网络使用…

次世代培训——我们从游戏美术发展历程讲起

自90后们记忆最初的小霸王游戏算起&#xff0c;中国游戏大致经历了从像素时代-预渲染时代-初世代-中世代-次世代这样几个阶段的变革。有趣的是&#xff0c;当主机、PC游戏早已跨过了像素时代&#xff0c;手游的兴起和发展却依然要遵从这一发展规律从头开始&#xff0c;当人们已…

FineReport智能报表工具- CSS修改控件样式

1. 概述 1.1 使用场景 在实际项目中&#xff0c;为了让 FineReport 报表中的控件和页面风格一致&#xff0c; 可以通过 CSS 修改控件的显示样式。 如下图所示&#xff0c;希望参数面板上文本框控件的边框变为红色&#xff0c;字体颜色变为蓝色。 除更换控件字体、修改边框颜色…

从风控中那些被标准化定义的问题谈起

说到风控业务中被标准化的定义问题&#xff0c;作为风控人最应该来谈谈这个内容&#xff0c;尤其是在数字化的风控内容上。数字化风控的标准化程度较高&#xff0c;在互金经过了一番喷薄的发展后&#xff0c;对于SOP守则&#xff0c;业务问题的定义及留给后续从业者可借鉴的资料…

足球人生:青春不过几届世界杯

&#x1f389;花有重开日&#xff0c;人无再少年。将近一个月的卡塔尔世界杯正式落帷幕&#xff0c;见证了最伟大的世界杯决赛&#xff0c;新老两代球王的巅峰对决&#xff0c;节奏拉满。诸神黄昏&#xff0c;球王加冕&#xff0c;最完美的结局。究竟怎样的颠沛流离才配得上这一…

web--拉灯泡切换黑天与白夜的精美动画

功能&#xff1a; 进入界面会出现一个灯泡&#xff08;下面有可以自由飘动也可以自由拉动的绳子&#xff09;&#xff0c;鼠标左键按住不松开可以拉动绳子&#xff0c;松开变化亮起&#xff0c;同时有拉响的清脆声响&#xff0c;把它放在web作业的设计里面绝对是非常非常不错的…

SQL注入总结复习

SQL注入总结复习 一、前提 1、web三层架构 学习SQL注入&#xff0c;前提必须要了解web程序的三层架构。 数据访问层&#xff08;DAL&#xff09;&#xff1a;主要负责对数据库进行增删改查&#xff0c;将存储在数据库中的数据提交给业务层&#xff0c;同时将业务层处理的数据…

第七章 集合相关知识

什么是集合 为了存储不同类型的多个对象, Java提供了一系列特殊的类, 这些类可以存储任意类型的对象&#xff0c;并且存储的长度可变,被统称为集合。集合可以简单理解为一个长度可变可以存储不同数据类型的动态数组。集合都位于java.uti包中,使用集合时必须导入java.util包。 …

前端二面必会手写面试题汇总

实现Vue reactive响应式 // Dep module class Dep {static stack []static target nulldeps nullconstructor() {this.deps new Set()}depend() {if (Dep.target) {this.deps.add(Dep.target)}}notify() {this.deps.forEach(w > w.update())}static pushTarget(t) {if …

LeetCode刷题复盘笔记—一文搞懂动态规划之300. 最长递增子序列问题(动态规划系列第二十七篇)

今日主要总结一下动态规划的一道题目&#xff0c;300. 最长递增子序列 题目&#xff1a;300. 最长递增子序列 Leetcode题目地址 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除…

想要月入过万?不防尝试一下Python这个职业!

自从20世纪90年代初发布以来&#xff0c;Python一直相当火爆&#xff0c;在这二十多年里&#xff0c;它的流行程度远远超过了C、C#、Java甚至Javascript。 Python为什么受欢迎&#xff1f; Python迅猛发展背后的一个主要驱动力是它学习起来相当容易&#xff0c;使用起来功能强…

程序员需要了解的硬核知识CPU

大家都是程序员&#xff0c;大家都是和计算机打交道的程序员&#xff0c;大家都是和计算机中软件硬件打交道的程序员&#xff0c;大家都是和CPU打交道的程序员&#xff0c;所以&#xff0c;不管你是玩儿硬件的还是做软件的&#xff0c;你的世界都少不了计算机最核心的 - CPU C…

【C语言进阶】通讯录不好用?进来,零基础带你写出自己的通讯录

目录 &#x1f929;前言&#x1f929;&#xff1a; &#x1f60e;正文&#xff1a;编写通讯录&#x1f60e;&#xff1a; 1.文件建立&#xff1a; ①.头文件Contact.h&#xff1a; ②.函数定义文件Contact.c&#xff1a; ③.工程测试文件test.c&#xff1a; 2.通讯录整体执行…

A White Paper on Neural Network Quantization--阅读笔记1

A White Paper on Neural Network Quantization--阅读笔记1一、模型量化的意义二、量化主要做什么三、目前量化主要分类四、量化基本知识介绍0、基本知识1、误差来源2、量化范围的设定五、量化方法介绍1、均匀仿射量化(Uniform affine quantization)2、对称均匀量化(Symmetric …

热门技术中的应用:微服务相关协议-第35讲-二进制类RPC协议:还是叫NBA吧,总说全称多费劲

前面我们讲了两个常用文本类的RPC协议,对于陌生人之间的沟通,用NBA、CBA这样的缩略语,会使得协议约定非常不方便。 在讲CDN和DNS的时候,我们讲过接入层的设计,对于静态资源或者动态资源静态化的部分都可以做缓存。但是对于下单、支付等交易场景,还是需要调用API。 对于…

基于yolov5的智慧交通监测系统

本项目实现了智慧交通监测、红绿灯监测、行人监测、车辆识别、斑马线闯红灯监测等多种监测功能。 目录 背景 演示效果&#xff1a; 检测代码样例&#xff1a; 最后的检测效果如图所示 项目具体的工作流程为&#xff1a; 总结&#xff1a; 背景 针对城市交通拥堵问题&#x…

Effective C++条款33:避免遮掩继承而来的名称(Avoid hiding inherited names)

Effective C条款33&#xff1a;避免遮掩继承而来的名称&#xff08;Avoid hiding inherited names&#xff09;条款33&#xff1a;避免遮掩继承而来的名称1、同名全局变量在局部作用域中被隐藏2、继承中的隐藏3、进一步论证——继承中的函数的隐藏4、如何将隐藏的行为进行覆盖4…

vTESTstudio入门到精通 - 如何自动化控制Simulation节点_03

我们工作中经常会遇到需要仿真大量的CAN/CANFD报文的情况,通常我们只能通过人工去测试,因为很难实现仿真控制大量报文的发送和停止?那我们该如何去解决呢? 今天我们主要来解决这个问题,通过CAPL去控制simulation节点的仿真发送和停止,最大限度的在实验室仿真实车的报文数…

段错误产生原因

嵌入式C开发&#xff0c;或多或少都遇到段错误&#xff08;segmentation fault &#xff09;。 下面是一些典型的段错误产生的原因&#xff1a; 访问不存在的内存地址 访问只读的内存地址 栈溢出 内存越界 …… 实例 1. 访问不存在的内存地址 #include <stdio.h>in…