diff --git a/geopandas/tests/test_geoseries.py b/geopandas/tests/test_geoseries.py index 42b585b..a20bae1 100644 --- a/geopandas/tests/test_geoseries.py +++ b/geopandas/tests/test_geoseries.py @@ -4,8 +4,12 @@ import os import json import shutil import tempfile + import numpy as np +import pandas as pd from numpy.testing import assert_array_equal +from pandas.util.testing import assert_series_equal + from shapely.geometry import (Polygon, Point, LineString, MultiPoint, MultiLineString, MultiPolygon) from shapely.geometry.base import BaseGeometry @@ -107,6 +111,12 @@ class TestSeries(unittest.TestCase): self.assertTrue(np.alltrue(self.g1.geom_equals_exact(self.g1, 0.001))) assert_array_equal(self.g1.geom_equals_exact(self.sq, 0.001), [False, True]) + def test_equal_comp_op(self): + s = GeoSeries([Point(x, x) for x in range(3)]) + res = s == Point(1, 1) + exp = pd.Series([False, True, False]) + assert_series_equal(res, exp) + def test_to_file(self): """ Test to_file and from_file """ tempfilename = os.path.join(self.tempdir, 'test.shp') diff --git a/geopandas/tests/test_pandas_methods.py b/geopandas/tests/test_pandas_methods.py new file mode 100644 index 0000000..e7670ca --- /dev/null +++ b/geopandas/tests/test_pandas_methods.py @@ -0,0 +1,237 @@ +from __future__ import absolute_import + +from distutils.version import LooseVersion + +from six import PY3 + +import pytest + +import numpy as np +import pandas as pd +from numpy.testing import assert_array_equal +from pandas.util.testing import assert_frame_equal, assert_series_equal + +import shapely +from shapely.geometry import Point + +from geopandas import GeoDataFrame, GeoSeries +from geopandas.tests.util import assert_geoseries_equal + + +@pytest.fixture +def s(): + return GeoSeries([Point(x, y) for x, y in zip(range(3), range(3))]) + + +@pytest.fixture +def df(): + return GeoDataFrame({'geometry': [Point(x, x) for x in range(3)], + 'value1': np.arange(3, dtype='int64'), + 'value2': np.array([1, 2, 1], dtype='int64')}) + + +def test_repr(s, df): + assert 'POINT' in repr(s) + assert 'POINT' in repr(df) + + +def test_indexing(s, df): + + # accessing scalar from the geometry (colunm) + exp = Point(1, 1) + assert s[1] == exp + assert s.loc[1] == exp + assert s.iloc[1] == exp + assert df.loc[1, 'geometry'] == exp + assert df.iloc[1, 0] == exp + + # multiple values + exp = GeoSeries([Point(2, 2), Point(0, 0)], index=[2, 0]) + assert_geoseries_equal(s.loc[[2, 0]], exp) + assert_geoseries_equal(s.iloc[[2, 0]], exp) + assert_geoseries_equal(s.reindex([2, 0]), exp) + assert_geoseries_equal(df.loc[[2, 0], 'geometry'], exp) + # TODO here iloc does not return a GeoSeries + assert_series_equal(df.iloc[[2, 0], 0], exp, check_series_type=False, + check_names=False) + + # boolean indexing + exp = GeoSeries([Point(0, 0), Point(2, 2)], index=[0, 2]) + mask = np.array([True, False, True]) + assert_geoseries_equal(s[mask], exp) + assert_geoseries_equal(s.loc[mask], exp) + assert_geoseries_equal(df[mask]['geometry'], exp) + assert_geoseries_equal(df.loc[mask, 'geometry'], exp) + + +def test_assignment(s, df): + exp = GeoSeries([Point(10, 10), Point(1, 1), Point(2, 2)]) + + s2 = s.copy() + s2[0] = Point(10, 10) + assert_geoseries_equal(s2, exp) + + s2 = s.copy() + s2.loc[0] = Point(10, 10) + assert_geoseries_equal(s2, exp) + + s2 = s.copy() + s2.iloc[0] = Point(10, 10) + assert_geoseries_equal(s2, exp) + + df2 = df.copy() + df2.loc[0, 'geometry'] = Point(10, 10) + assert_geoseries_equal(df2['geometry'], exp) + + df2 = df.copy() + df2.iloc[0, 0] = Point(10, 10) + assert_geoseries_equal(df2['geometry'], exp) + + +def test_assign(df): + res = df.assign(new=1) + exp = df.copy() + exp['new'] = 1 + assert isinstance(res, GeoDataFrame) + assert_frame_equal(res, exp, ) + + +def test_astype(s): + + with pytest.raises(TypeError): + s.astype(int) + + assert s.astype(str)[0] == 'POINT (0 0)' + + +def test_to_csv(df): + + exp = ('geometry,value1,value2\nPOINT (0 0),0,1\nPOINT (1 1),1,2\n' + 'POINT (2 2),2,1\n') + assert df.to_csv(index=False) == exp + + +@pytest.mark.skipif(str(pd.__version__) < LooseVersion('0.17'), + reason="s.max() does not raise on 0.16") +def test_numerical_operations(s, df): + + # df methods ignore the geometry column + exp = pd.Series([3, 4], index=['value1', 'value2']) + assert_series_equal(df.sum(), exp) + + # series methods raise error + with pytest.raises(TypeError): + s.sum() + + if PY3: + # in python 2, objects are still orderable + with pytest.raises(TypeError): + s.max() + + with pytest.raises(TypeError): + s.idxmax() + + # numerical ops raise an error + with pytest.raises(TypeError): + df + 1 + + with pytest.raises(TypeError): + s + 1 + + # boolean comparisons work + res = df == 100 + exp = pd.DataFrame(False, index=df.index, columns=df.columns) + assert_frame_equal(res, exp) + + +def test_where(s): + res = s.where(np.array([True, False, True])) + exp = s.copy() + exp[1] = np.nan + assert_series_equal(res, exp) + + +def test_select_dtypes(df): + res = df.select_dtypes(include=[np.number]) + exp = df[['value1', 'value2']] + assert_frame_equal(res, exp) + + +# Missing values + + +@pytest.mark.xfail +def test_fillna(): + # this currently does not work (it seems to fill in the second coordinate + # of the point + s2 = GeoSeries([Point(0, 0), None, Point(2, 2)]) + res = s2.fillna(Point(1, 1)) + assert_geoseries_equal(res, s) + + +@pytest.mark.xfail +def test_dropna(): + # this currently does not work (doesn't drop) + s2 = GeoSeries([Point(0, 0), None, Point(2, 2)]) + res = s2.dropna() + exp = s2.loc[[0, 2]] + assert_geoseries_equal(res, exp) + + +def test_isnull(): + for NA in [None, np.nan]: + s2 = GeoSeries([Point(0, 0), NA, Point(2, 2)]) + res = s2.isnull() + exp = pd.Series([False, True, False]) + assert_series_equal(res, exp) + res = s2.notnull() + assert_series_equal(res, ~exp) + + +# Groupby / algos + + +@pytest.mark.xfail +def test_unique(): + # this currently raises a TypeError + s = GeoSeries([Point(0, 0), Point(0, 0), Point(2, 2)]) + exp = np.array([Point(0, 0), Point(2, 2)]) + assert_array_equal(s.unique(), exp) + +@pytest.mark.xfail +def test_value_counts(): + # each object is considered unique + s = GeoSeries([Point(0, 0), Point(1, 1), Point(0, 0)]) + res = s.value_counts() + exp = pd.Series([2, 1], index=[Point(0, 0), Point(1, 1)]) + assert_series_equal(res, exp) + + +def test_groupby(df): + + # counts work fine + res = df.groupby('value2').count() + exp = pd.DataFrame({'geometry': [2, 1], 'value1': [2, 1], + 'value2': [1, 2]}).set_index('value2') + assert_frame_equal(res, exp) + + # reductions ignore geometry column + res = df.groupby('value2').sum() + exp = pd.DataFrame({'value1': [2, 1], + 'value2': [1, 2]}, dtype='int64').set_index('value2') + assert_frame_equal(res, exp) + + # applying on the geometry column + res = df.groupby('value2')['geometry'].apply(lambda x: x.cascaded_union) + exp = pd.Series([shapely.geometry.MultiPoint([(0, 0), (2, 2)]), + Point(1, 1)], + index=pd.Index([1, 2], name='value2'), name='geometry') + assert_series_equal(res, exp) + + +def test_groupby_groups(df): + g = df.groupby('value2') + res = g.get_group(1) + assert isinstance(res, GeoDataFrame) + exp = df.loc[[0, 2]] + assert_frame_equal(res, exp)