| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- from __future__ import division, print_function, absolute_import
- import datetime
- import os
- import sys
- from os.path import join as pjoin
- if sys.version_info[0] >= 3:
- from io import StringIO
- else:
- from cStringIO import StringIO
- import numpy as np
- from numpy.testing import (assert_array_almost_equal,
- assert_array_equal, assert_equal, assert_)
- import pytest
- from pytest import raises as assert_raises
- from scipy.io.arff.arffread import loadarff
- from scipy.io.arff.arffread import read_header, parse_type, ParseArffError
- data_path = pjoin(os.path.dirname(__file__), 'data')
- test1 = pjoin(data_path, 'test1.arff')
- test2 = pjoin(data_path, 'test2.arff')
- test3 = pjoin(data_path, 'test3.arff')
- test4 = pjoin(data_path, 'test4.arff')
- test5 = pjoin(data_path, 'test5.arff')
- test6 = pjoin(data_path, 'test6.arff')
- test7 = pjoin(data_path, 'test7.arff')
- test8 = pjoin(data_path, 'test8.arff')
- expect4_data = [(0.1, 0.2, 0.3, 0.4, 'class1'),
- (-0.1, -0.2, -0.3, -0.4, 'class2'),
- (1, 2, 3, 4, 'class3')]
- expected_types = ['numeric', 'numeric', 'numeric', 'numeric', 'nominal']
- missing = pjoin(data_path, 'missing.arff')
- expect_missing_raw = np.array([[1, 5], [2, 4], [np.nan, np.nan]])
- expect_missing = np.empty(3, [('yop', float), ('yap', float)])
- expect_missing['yop'] = expect_missing_raw[:, 0]
- expect_missing['yap'] = expect_missing_raw[:, 1]
- class TestData(object):
- def test1(self):
- # Parsing trivial file with nothing.
- self._test(test4)
- def test2(self):
- # Parsing trivial file with some comments in the data section.
- self._test(test5)
- def test3(self):
- # Parsing trivial file with nominal attribute of 1 character.
- self._test(test6)
- def _test(self, test_file):
- data, meta = loadarff(test_file)
- for i in range(len(data)):
- for j in range(4):
- assert_array_almost_equal(expect4_data[i][j], data[i][j])
- assert_equal(meta.types(), expected_types)
- def test_filelike(self):
- # Test reading from file-like object (StringIO)
- f1 = open(test1)
- data1, meta1 = loadarff(f1)
- f1.close()
- f2 = open(test1)
- data2, meta2 = loadarff(StringIO(f2.read()))
- f2.close()
- assert_(data1 == data2)
- assert_(repr(meta1) == repr(meta2))
- @pytest.mark.skipif(sys.version_info < (3, 6),
- reason='Passing path-like objects to IO functions requires Python >= 3.6')
- def test_path(self):
- # Test reading from `pathlib.Path` object
- from pathlib import Path
- with open(test1) as f1:
- data1, meta1 = loadarff(f1)
- data2, meta2 = loadarff(Path(test1))
- assert_(data1 == data2)
- assert_(repr(meta1) == repr(meta2))
- class TestMissingData(object):
- def test_missing(self):
- data, meta = loadarff(missing)
- for i in ['yop', 'yap']:
- assert_array_almost_equal(data[i], expect_missing[i])
- class TestNoData(object):
- def test_nodata(self):
- # The file nodata.arff has no data in the @DATA section.
- # Reading it should result in an array with length 0.
- nodata_filename = os.path.join(data_path, 'nodata.arff')
- data, meta = loadarff(nodata_filename)
- expected_dtype = np.dtype([('sepallength', '<f8'),
- ('sepalwidth', '<f8'),
- ('petallength', '<f8'),
- ('petalwidth', '<f8'),
- ('class', 'S15')])
- assert_equal(data.dtype, expected_dtype)
- assert_equal(data.size, 0)
- class TestHeader(object):
- def test_type_parsing(self):
- # Test parsing type of attribute from their value.
- ofile = open(test2)
- rel, attrs = read_header(ofile)
- ofile.close()
- expected = ['numeric', 'numeric', 'numeric', 'numeric', 'numeric',
- 'numeric', 'string', 'string', 'nominal', 'nominal']
- for i in range(len(attrs)):
- assert_(parse_type(attrs[i][1]) == expected[i])
- def test_badtype_parsing(self):
- # Test parsing wrong type of attribute from their value.
- ofile = open(test3)
- rel, attrs = read_header(ofile)
- ofile.close()
- for name, value in attrs:
- assert_raises(ParseArffError, parse_type, value)
- def test_fullheader1(self):
- # Parsing trivial header with nothing.
- ofile = open(test1)
- rel, attrs = read_header(ofile)
- ofile.close()
- # Test relation
- assert_(rel == 'test1')
- # Test numerical attributes
- assert_(len(attrs) == 5)
- for i in range(4):
- assert_(attrs[i][0] == 'attr%d' % i)
- assert_(attrs[i][1] == 'REAL')
- # Test nominal attribute
- assert_(attrs[4][0] == 'class')
- assert_(attrs[4][1] == '{class0, class1, class2, class3}')
- def test_dateheader(self):
- ofile = open(test7)
- rel, attrs = read_header(ofile)
- ofile.close()
- assert_(rel == 'test7')
- assert_(len(attrs) == 5)
- assert_(attrs[0][0] == 'attr_year')
- assert_(attrs[0][1] == 'DATE yyyy')
- assert_(attrs[1][0] == 'attr_month')
- assert_(attrs[1][1] == 'DATE yyyy-MM')
- assert_(attrs[2][0] == 'attr_date')
- assert_(attrs[2][1] == 'DATE yyyy-MM-dd')
- assert_(attrs[3][0] == 'attr_datetime_local')
- assert_(attrs[3][1] == 'DATE "yyyy-MM-dd HH:mm"')
- assert_(attrs[4][0] == 'attr_datetime_missing')
- assert_(attrs[4][1] == 'DATE "yyyy-MM-dd HH:mm"')
- def test_dateheader_unsupported(self):
- ofile = open(test8)
- rel, attrs = read_header(ofile)
- ofile.close()
- assert_(rel == 'test8')
- assert_(len(attrs) == 2)
- assert_(attrs[0][0] == 'attr_datetime_utc')
- assert_(attrs[0][1] == 'DATE "yyyy-MM-dd HH:mm Z"')
- assert_(attrs[1][0] == 'attr_datetime_full')
- assert_(attrs[1][1] == 'DATE "yy-MM-dd HH:mm:ss z"')
- class TestDateAttribute(object):
- def setup_method(self):
- self.data, self.meta = loadarff(test7)
- def test_year_attribute(self):
- expected = np.array([
- '1999',
- '2004',
- '1817',
- '2100',
- '2013',
- '1631'
- ], dtype='datetime64[Y]')
- assert_array_equal(self.data["attr_year"], expected)
- def test_month_attribute(self):
- expected = np.array([
- '1999-01',
- '2004-12',
- '1817-04',
- '2100-09',
- '2013-11',
- '1631-10'
- ], dtype='datetime64[M]')
- assert_array_equal(self.data["attr_month"], expected)
- def test_date_attribute(self):
- expected = np.array([
- '1999-01-31',
- '2004-12-01',
- '1817-04-28',
- '2100-09-10',
- '2013-11-30',
- '1631-10-15'
- ], dtype='datetime64[D]')
- assert_array_equal(self.data["attr_date"], expected)
- def test_datetime_local_attribute(self):
- expected = np.array([
- datetime.datetime(year=1999, month=1, day=31, hour=0, minute=1),
- datetime.datetime(year=2004, month=12, day=1, hour=23, minute=59),
- datetime.datetime(year=1817, month=4, day=28, hour=13, minute=0),
- datetime.datetime(year=2100, month=9, day=10, hour=12, minute=0),
- datetime.datetime(year=2013, month=11, day=30, hour=4, minute=55),
- datetime.datetime(year=1631, month=10, day=15, hour=20, minute=4)
- ], dtype='datetime64[m]')
- assert_array_equal(self.data["attr_datetime_local"], expected)
- def test_datetime_missing(self):
- expected = np.array([
- 'nat',
- '2004-12-01T23:59',
- 'nat',
- 'nat',
- '2013-11-30T04:55',
- '1631-10-15T20:04'
- ], dtype='datetime64[m]')
- assert_array_equal(self.data["attr_datetime_missing"], expected)
- def test_datetime_timezone(self):
- assert_raises(ValueError, loadarff, test8)
|