在Numpy genfromtxt中加载日期

8

我正在尝试使用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中遇到了以下错误:

类型错误:必须是字符串,而不是字节

问题在于有很多列,所以我更喜欢避免指定所有的列类型(这些列基本上都是数值型的)。


2
你能分享一部分你的 data.csv 文件吗? - Gabriel
3个回答

7
问题在于传递给 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')

1
谢谢。我不明白为什么genfromtxt选择的类型是字节数组而不是字符串...无论如何,我按照你的修改进行了操作,但是在加载时出现了另一个错误:ConverterError: 转换器#0已锁定,无法升级:(对于值“b'2011-01-01 00:00:00''”,发生在第1行),尽管日期是有效的... - Mark Morrisson
1
@MarkMorrisson 看一下我的更新答案!希望这可以帮到你。 - Nelewout
谢谢,现在它完美地工作了!你能解释一下UTF8的技巧吗?导入日期看起来很复杂... - Mark Morrisson
@MarkMorrisson 您没有为列指定 dtype,因此 numpy 猜测最佳匹配,在这种情况下是一个字节字符串。我们只需要将其解码为更“人类”的格式,例如 UTF-8。如果此答案解决了您的问题,请考虑将其标记为已接受 :)。 - Nelewout
哦,我明白问题了,对字节字符串应用str()函数会在最终字符串中保留'b',这太荒谬了... - Mark Morrisson
@MarkMorrison 格式规范b'' 字符串是有效的字符串表示形式,但对于这个特定的用例来说并不是期望的字符串表示形式。 - Nelewout

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

Our code should be:

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,则会逐个确定每个列的数据类型。
名称:{None、True、str、sequence},可选。如果 names 为 True,则字段名称将从第一行读取,跳过第一个 skip_header 行。此行可以选择由注释分隔符进行分隔。如果 names 是序列或以逗号分隔的单个字符串,则这些名称将用于定义结构化 dtype 中的字段名称。如果 names 为 None,则将使用 dtype 字段的名称(如果有)。
编码:str,可选。用于解码输入文件的编码。
要提取数据并处理数据,我们可以:
levels= data['level']
dates= data['date']

-3

这是一个非常好的想法。我曾经遇到过同样的问题,当我尝试在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
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接