【问题标题】:Loading a date in Numpy genfromtxt在 Numpy genfromtxt 中加载日期
【发布时间】:2016-04-12 01:01:10
【问题描述】:

我正在尝试使用 Numpy genfromtxt 导入一个简单的 CSV 文件,但无法将第一列的数据转换为日期。

这是我的代码:

import numpy as np
from datetime import datetime

str2date = lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S')

data = np.genfromtxt('C:\\\\data.csv',dtype=None,names=True, delimiter=',', converters = {0: str2date})

我在 str2date 中收到以下错误:

TypeError: 必须是 str,而不是 bytes

问题是有很多列,所以我宁愿避免指定所有列类型(基本上是数字)。

【问题讨论】:

  • 您能分享您的data.csv 文件的至少一部分吗?

标签: python numpy genfromtxt


【解决方案1】:

当我们要在csv文件中读取一个值代表日期的列时,我们必须考虑它是如何表示的,例如:

- 2021/12/05 = %Y/%m/%d
- 21/12/05 = %y/%m/%d
- 05/12/2021 = %d/%m/%Y
- 05/12/21 = %d/%m/%y
- 05-12-21 = %d-%m-%y
- ...

在创建 lambda 函数时必须考虑这些表示日期的方法,我们将在 NumPy getfromtxt() 方法中用作转换器。该方法接受多个参数,其中我们可以找到可以以不同方式使用的转换器,在这种情况下,将列的值转换为日期类型的值

converters variable, optional

    The set of functions that convert the data of a column to a value. The converters can also be used to provide a default value for missing data: 
     converters = {num_col: lambda_function }.

num_col - 表示函数将应用到的列的编号

lambda_function - 表示我们将为转换构建的函数

对于这个例子,我们将有两列,日期和级别,用 (;) 和 utf-8 编码分隔:

date level
02-03-15 232.8
09-03-15 233.0
16-03-15 233.2
23-03-15 233.6
30-03-15 233.9
06-04-15 234.3
13-04-15 234.8
20-04-15 235.3
27-04-15 235.9

我们的代码应该是:

import numpy as np
from datetime import datetime

str2date = lambda x: datetime.strptime(x, '%d-%m-%y')
data = np.genfromtxt(file_path, delimiter=';', dtype=None, names=True, converters = {0: str2date}, encoding='utf-8')

变量file_path将替换为文件所在的目录,包括文件名和扩展名。

分隔符:str、int或sequence,可选。用于分隔值的字符串。默认情况下,任何连续的空格都充当分隔符。也可以提供整数或整数序列作为每个字段的宽度。

dtype:dtype,可选。结果数组的数据类型。如果为 None,则 dtypes 将由每列的内容单独确定。

名称:{None, True, str, sequence},可选。如果名称为 True,则从第一个 skip_header 行之后的第一行读取字段名称。此行可以选择由注释分隔符进行。如果名称是逗号分隔名称的序列或单字符串,则名称将用于定义结构化 dtype 中的字段名称。如果名称为 None,则将使用 dtype 字段的名称(如果有)。

编码:str,可选。用于解码输入文件的编码。

要提取数据并使用它,我们可以:

levels= data['level']
dates= data['date']

【讨论】:

    【解决方案2】:

    这是个好主意。当我尝试对 Python 3.4 使用 numpy 时,我遇到了同样的问题。对于 python 2.7.10,它不是必需的。谢谢你。 :-) 这是我的示例。

    文件输入:

    06-07-2016,95.5300,30877540.0000,94.6000,95.6600,94.3700
    05-07-2016,95.0400,27553750.0000,95.3900,95.4000,94.4600
    01-07-2016,95.8900,25982080.0000,95.4900,96.4650,95.3300*
    

    代码:

    dates = numpy.loadtxt(
                'data.csv',
                dtype = object,
                converters={0: lambda x: datetime.datetime.strptime(x.decode("utf-8"), "%d-%m-%Y")},
                delimiter=',',
                usecols=(0,),
                unpack=True
    )
    

    【讨论】:

      【解决方案3】:

      问题是传递给str2date 的参数是b'%Y-%m-%d %H:%M:%S' 这种形式。这些是字节,它们不能被解析为日期时间对象。不过,该问题的解决方案非常简单,因为您应该将字节字符串解码为 UTF-8 字符串:

      str2date = lambda x: datetime.strptime(x.decode("utf-8"), '%Y-%m-%d %H:%M:%S')

      【讨论】:

      • 谢谢。我不明白为什么 genfromtxt 选择的类型是字节数组而不是字符串......无论如何,我做了你的修改,运行加载但又得到另一个错误:ConverterError: Converter #0 is locked and cannot be upgrade:(尽管日期有效,但值 'b'2011-01-01 00:00:00'' 的第 1 行发生...
      • @MarkMorrisson 看到我更新的答案!我希望这会有所帮助。
      • 谢谢,它现在可以完美运行了!你能解释一下 UTF8 的诀窍吗?导入日期看起来很复杂...
      • @MarkMorrisson 您没有为您的列指定dtype,因此numpy 猜测可能的最佳拟合,它认为这是一个字节字符串。我们只需要将其解码为更“人性化”的格式,例如 UTF-8。如果此答案解决了您的问题,请考虑将其标记为已接受:)。
      • 哦,我明白了问题所在,应用于字节字符串的 str() 将 'b' 保留在最终字符串中,这很荒谬......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-10
      • 2013-01-14
      • 2023-03-08
      • 1970-01-01
      • 2015-07-27
      • 2015-11-22
      • 2023-04-01
      相关资源
      最近更新 更多