我正在尝试执行以下操作: 我下载了一个包含过去180天银行交易的csv文件。 我想阅读这个csv文件,然后用数据做一些图。 为此,我设置了一个程序,该程序读取csv文件并通过关键字使数据可用。 例如在csv文件中有一列“Buchungstag”。 我用date关键字等替换它。
import numpy as np
import matplotlib.pylab as mpl
import csv
class finanz():
def __init__(self):
path = "/home/***/"
self.dataFileName = path + "test.csv"
self.data_read = open(self.dataFileName, 'r')
self._columns = {}
self._columns[0] = ["date", "Buchungstag", "", "S15"]
self._columns[1] = ["value", "Umsatz", "Euro", "f8"]
self._ident = {"Buchungstag":"date", "Umsatz in {0}":"value"}
self.base = 1205.30
self._readData()
def _readData(self):
r = csv.DictReader(self.data_read, delimiter=';')
dtype = map(lambda x: (self._columns[x][0],self._columns[x][3]),range(len(self._columns)))
self.data = np.recarray((2), dtype=dtype)
desiredKeys = map(lambda x:x, self._ident.iterkeys())
for i, x in enumerate(r):
for k in desiredKeys:
if k == "Umsatz in {0}":
v = np.float(x[k].replace(",", "."))+self.base
else:
v = x[k]
self.data[self._ident[k]][i] = v
def getAllData(self):
return self.data.copy()
a = finanz()
b = a.getAllData()
print type(b)
print type(b['value']),type(b['date'])
示例数据
"Buchungstag";"Wertstellung (Valuta)";"Vorgang";"Buchungstext";"Umsatz in {0}";
"02.06.2015";"02.06.2015";"Lastschrift/Belast.";"Auftraggeber: abc";"-3,75";
我现在的问题是为什么键入(b ['date'])类'numpy.core.records.recarray'并键入(b ['value'])类型'numpy.ndarray'??
我的第二个问题是如何以matplotlib可以使用的格式“保存”日期?
第三个也是最后一个问题是如何检查csv文件中的许多行(用于创建空的self.data数组)
THX!
答案 0 :(得分:0)
在没有额外代码的情况下重复生成数组:
In [230]: dt=np.dtype([('date', 'S15'), ('value', '<f8')])
In [231]: data=np.recarray((2,),dtype=dt)
In [232]: type(data['date'])
Out[232]: numpy.core.records.recarray
In [233]: type(data['value'])
Out[233]: numpy.ndarray
一个字段作为ndarray
返回,另一个字段作为recarray
返回的事实并不重要。这就是recarray
类的设置方式。
现在我们主要使用'结构化数组',例如用
创建data1=np.empty((2,),dtype=dt)
或填充'0s':
data1=np.zeros((2,),dtype=dt)
# array([('', 0.0), ('', 0.0)],
dtype=[('date', 'S15'), ('value', '<f8')])
有了这个,data1['date']
和['value']
都是ndarray
。 recarray
是旧版本,仍然兼容,但结构化数组的语法和行为更加一致。有很多关于结构化数组的SO问题,其中许多由np.genfromtxt
生成,应用于像你这样的csv文件。
我可以结合这个想法,加上我的评论(关于列表追加):
def _readData(self):
r = csv.DictReader(self.data_read, delimiter=';')
if self._columns[0][1].endswith('tag'):
self._columns[0][2] = 'datetime64[D]'
dtype = map(lambda x: (self._columns[x][0],self._columns[x][3]),range(len(self._columns)))
desiredKeys = map(lambda x:x, self._ident.iterkeys())
data = []
for x in r:
aline = np.zeros((1,), dtype=dtype)
for k in desiredKeys:
if k == "Umsatz in {0}":
v = np.float(x[k].replace(",", "."))+self.base
else:
v = x[k]
v1 = v.split('.')
if len(v1)==3: # convert date to yyyyy-mm-dd format
v = '%s-%s-%s'%(v1[2],v1[1],v1[0])
aline[self._ident[k]] = v
data.append(aline)
self.data = np.concatenate(data)
生成b
之类的:
array([(datetime.date(2015, 6, 2), 1201.55),
(datetime.date(2015, 6, 2), 1201.55),
(datetime.date(2015, 6, 2), 1201.55)],
dtype=[('date', '<M8[D]'), ('value', '<f8')])
我相信genfromtxt
会将每一行收集为一个元组,并在最后创建数组。结构化数组的文档显示它们可以从
np.array([(item1, item2), (item3, item4),...], dtype=dtype)
我选择为每一行构建一个数组,并在最后连接它们,因为这需要对代码进行更少的更改。
我也更改了该功能,因此它将'tag'列转换为np.datetime64
dtype。关于使用该dtype有许多SO问题。我相信它可以在matplotlib
中使用,但我没有相关经验。