从.csv文件读取值并转换为浮动数组
我遇到了一个小编程问题。我需要从一个.csv文件中读取数据,这个文件的内容大概是这样的:
2011-06-19 17:29:00.000,72,44,56,0.4772,0.3286,0.8497,31.3587,0.3235,0.9147,28.5751,0.3872,0.2803,0,0.2601,0.2073,0.1172,0,0.0,0,5.8922,1,0,0,0,1.2759
现在,我需要处理整个文件,里面有很多像这样的行,并把它们解析成numpy数组。到目前为止,我已经能够用类似下面的代码把它们放进一个大的字符串对象里:
order_hist = np.loadtxt(filename_input,delimiter=',',dtype={'names': ('Year', 'Mon', 'Day', 'Stock', 'Action', 'Amount'), 'formats': ('i4', 'i4', 'i4', 'S10', 'S10', 'i4')})
这个文件的格式目前包含一组S20数据类型。我需要把大ORDER_HIST数据类型中的所有数据提取出来,分成每一列的数组。我不知道怎么保存日期时间这一列(现在我把它当作字符串处理)。其余的我需要转换成浮点数,但下面的代码给我报错:
temparr=float[:len(order_hist)]
for x in range(len(order_hist['Stock'])):
temparr[x]=float(order_hist['Stock'][x]);
有没有人能告诉我怎么把所有列转换成我需要的数组???或者能给我指个链接让我学习一下?
1 个回答
嘿,今天我给你带来了一个好东西。numpy.genfromtxt 有一个叫 converters
的参数,这个参数可以让你在读取文件时为每一列指定一个函数。这个函数会接收 CSV 文件中的字符串值,然后返回的结果会变成 numpy 数组中对应的值。
而且,dtype = None
这个参数告诉 genfromtxt
自动猜测每一列的数据类型。特别是,对于数字列,它会自动转换成合适的数据类型。
举个例子,假设你的数据文件包含:
2011-06-19 17:29:00.000,72,44,56
那么,
import numpy as np
import datetime as DT
def make_date(datestr):
return DT.datetime.strptime(datestr, '%Y-%m-%d %H:%M:%S.%f')
arr = np.genfromtxt(filename, delimiter = ',',
converters = {'Date':make_date},
names = ('Date', 'Stock', 'Action', 'Amount'),
dtype = None)
print(arr)
print(arr.dtype)
会得到:
(datetime.datetime(2011, 6, 19, 17, 29), 72, 44, 56)
[('Date', '|O4'), ('Stock', '<i4'), ('Action', '<i4'), ('Amount', '<i4')]
你的真实 CSV 文件可能有更多的列,所以你可能需要在 names
中添加更多的项目,但其他的部分应该还是适用的。
如果你不太在意额外的列,可以给它们起个随便的名字,比如这样:
arr = np.genfromtxt(filename, delimiter=',',
converters={'Date': make_date},
names=('Date', 'Stock', 'Action', 'Amount') +
tuple('col{i}'.format(i=i) for i in range(22)),
dtype = None)
会得到:
(datetime.datetime(2011, 6, 19, 17, 29), 72, 44, 56, 0.4772, 0.3286, 0.8497, 31.3587, 0.3235, 0.9147, 28.5751, 0.3872, 0.2803, 0, 0.2601, 0.2073, 0.1172, 0, 0.0, 0, 5.8922, 1, 0, 0, 0, 1.2759)
你可能还会对 pandas 模块感兴趣,它是建立在 numpy
之上的,可以让解析 CSV 文件变得更加简单和强大:它有一个 pandas.read_csv 函数,其中的 parse_dates = True
参数可以自动解析日期字符串(使用 dateutil)。
使用 pandas,你可以这样解析你的 CSV 文件:
df = pd.read_csv(filename, parse_dates = [0,1], header = None,
names=('Date', 'Stock', 'Action', 'Amount') +
tuple('col{i}'.format(i=i) for i in range(22)))
注意,这里不需要指定 make_date
函数。为了更清楚地说明,pandas.read_csv
返回的是一个 DataFrame
,而不是 numpy 数组。这个 DataFrame
可能对你更有用,但你要知道它是一个不同的对象,有很多新的方法可以使用和探索。