Skip to content

New Interval / IntervalIndex behavior spec #16386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 63 commits into from
Dec 28, 2017
Merged

New Interval / IntervalIndex behavior spec #16386

merged 63 commits into from
Dec 28, 2017

Conversation

alexlenail
Copy link
Contributor

@alexlenail alexlenail commented May 18, 2017

@jreback

@codecov
Copy link

codecov bot commented May 18, 2017

Codecov Report

Merging #16386 into master will decrease coverage by 0.01%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #16386      +/-   ##
==========================================
- Coverage   91.57%   91.56%   -0.02%     
==========================================
  Files         150      150              
  Lines       48913    48959      +46     
==========================================
+ Hits        44794    44831      +37     
- Misses       4119     4128       +9
Flag Coverage Δ
#multiple 89.93% <ø> (-0.01%) ⬇️
#single 41.13% <ø> (-0.04%) ⬇️
Impacted Files Coverage Δ
pandas/io/json/json.py 92.08% <0%> (-0.48%) ⬇️
pandas/tseries/offsets.py 96.78% <0%> (-0.29%) ⬇️
pandas/core/indexes/period.py 92.77% <0%> (-0.23%) ⬇️
pandas/core/indexes/datetimelike.py 97.13% <0%> (-0.07%) ⬇️
pandas/core/ops.py 90.17% <0%> (-0.04%) ⬇️
pandas/core/indexes/timedeltas.py 91.06% <0%> (-0.03%) ⬇️
pandas/core/resample.py 96.34% <0%> (-0.02%) ⬇️
pandas/core/indexes/base.py 96.44% <0%> (-0.01%) ⬇️
pandas/core/groupby.py 92.07% <0%> (-0.01%) ⬇️
pandas/core/panel.py 96.85% <0%> (ø) ⬆️
... and 7 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ef75390...acefcb0. Read the comment docs.

@shoyer
Copy link
Member

shoyer commented May 18, 2017

I just took a quick look and this looks great!

One comment: it would be great to convert your tests for Series indexing into unit tests on the IntervalIndex itself, which would let us avoids testing the unrelated indexing code. In most cases, the methods to test are .get_loc and .get_indexer.

@alexlenail
Copy link
Contributor Author

@shoyer sorry, I might need a little more explanation. Where can I find those methods, i.e. where should I move my unit tests to?

@shoyer
Copy link
Member

shoyer commented May 18, 2017

@jreback jreback added Interval Interval data type Testing pandas testing functions or related to the test suite labels May 19, 2017
@alexlenail
Copy link
Contributor Author

@shoyer sorry, still lost -- don't know the internals of pandas too well I guess.

What exactly do you mean by putting the unit tests on IntervalIndex itself rather than on the indexing code? I think the reason I'm confused is I don't know how .loc works -- does it call .get_loc? What is the "bottom" method that we should be testing? I don't see loc in pandas/pandas/core/indexes/interval.py ...

@shoyer
Copy link
Member

shoyer commented May 21, 2017 via email

@alexlenail
Copy link
Contributor Author

@shoyer

  1. should get_loc really return an int if there's a single match and an array if there are multiple matches?

  2. Where is the implementation of get_loc? Is it in the pyx / pxi.in? Where can I learn more about what those are?

  3. Does __getitem__ go through get_loc? If not, where should I move the __getitem__ tests?

@alexlenail
Copy link
Contributor Author

  1. In indexing/test_interval.py, there's test_loc_with_scalar and in indexes/test_interval.py there's test_get_loc_value which tests the same logic, I think. It might make sense to do a slightly more complete re-shuffling of the tests if we want to make each test unique, and assign a correct file for each test..

@shoyer
Copy link
Member

shoyer commented May 22, 2017

@zfrenchee

should get_loc really return an int if there's a single match and an array if there are multiple matches?

Yes.

Where is the implementation of get_loc? Is it in the pyx / pxi.in? Where can I learn more about what those are?

All these methods are defined on IntervalIndex: https://github.com/pandas-dev/pandas/blob/49ec31bbaeca81a6f58fc1be26fe80f3ac188cdd/pandas/core/indexes/interval.py

Does getitem go through get_loc? If not, where should I move the getitem tests?

Yes, almost always. The notable exception is for cases where it performs integer indexing rather than label based indexing.

In indexing/test_interval.py, there's test_loc_with_scalar and in indexes/test_interval.py there's test_get_loc_value which tests the same logic, I think.

The tests in indexing/test_interval.py test indexing on objects with an IntervalIndex. These are useful as integration tests.

The tests in indexes/test_interval.py test the IntervalIndex behavior alone, and thus are unit tests.

Both unit tests and integration tests are useful, but only unit tests need to comprehensively check every possible behavior (there are too many ways to combine things for integration tests).

@alexlenail
Copy link
Contributor Author

alexlenail commented May 23, 2017

The tests in indexing/test_interval.py test indexing on objects with an IntervalIndex. These are useful as integration tests.

The tests in indexes/test_interval.py test the IntervalIndex behavior alone, and thus are unit tests.

@shoyer, @jreback suggested adding the tests to indexing/test_interval.py but all the tests are really unit tests. Should I move all my tests in that case? I think that makes sense, just want the okay from you.

@alexlenail
Copy link
Contributor Author

@shoyer still waiting to hear about where these tests belong. Since I basically only added unit tests, I think it might make sense to move all the tests to indexes from indexing. Let me know what you think.

@shoyer
Copy link
Member

shoyer commented May 24, 2017

@zfrenchee in your case, yes, I think almost all of your unit tests should be in indexes. We already have plenty of integration tests (though a few of those might need fixes).

@alexlenail
Copy link
Contributor Author

@shoyer would you take a look? I added a new test_get_loc_value function, and moved all my covers / overlaps tests to indexes for good measure.

  1. I'm happy to trim the overlaps / covers tests down if both those functions will end up calling .get_loc.

  2. I'm happy to add overlaps / covers integration tests (right now there are no more tests for those functions in indexing.

  3. I haven't written any new slice_locs tests, mostly because I'm not sure what this is testing on the index / am generally confused about slicing.

  4. there are a couple "updated" integration tests that still need work in indexing.

Let me know what you think / where we should go from here

@shoyer
Copy link
Member

shoyer commented May 26, 2017

I haven't written any new slice_locs tests, mostly because I'm not sure what this is testing on the index / am generally confused about slicing.

slice_locs is used for label based indexing with slices. Basically, series.loc[start:stop] gets implemented as something like series.iloc[series.index.slice_locs(start, stop). (Don't worry about step, it's only allowed to be an integer and doesn't really effect how this works.)

To gain some intuition for how this should work, I recommend trying indexing a series with integer labels, e.g., s = pd.Series(range(5)) with various integer and float bounds. Also try with out of order index=[3, 4, 0, 1, 2], duplicate index=[0, 0, 1, 1, 2] or decreasing index=reversed(range(5)) indexes.

I think IntervalIndex handles slicing consistently with Int64Index, but I haven't tested it much recently.

Generally, I like the way this is coming together -- these test cases will be super helpful! See inline comments below.


right = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed='right')

pytest.raises(KeyError, right.get_loc(-0.5) )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work. You need to use one of these forms:

pytest.raises(KeyError, right.get_loc, -0.5)

or:

with pytest.raises(KeyError):
    right.get_loc(-0.5)

The second version is usually easier to read because you can use normal syntax, but in this case (with one argument) there might be something to be said for fitting on one line.


pytest.raises(KeyError, right.get_loc(-0.5) )
pytest.raises(KeyError, right.get_loc(0) )
assert right.get_loc(0.5) == 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per PEP8, we don't use spaces for alignment. Just a single space is preferred.

pytest.raises(KeyError, right.get_loc(Interval(0, 2, closed='both')) )
pytest.raises(KeyError, right.get_loc(Interval(2.5, 3, closed='both')) )

left = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed='left')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is long enough for one test. Can you make this a second method, e.g., test_get_loc_vlaue_closed_left?


idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)])

assert Interval(1, 3, closed='right').covers(idx) == np.array([1, 2])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to use np.testing.assert_array_equal here instead of == (remember numpy arrays overload == to do element-wise comparison).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope use

tm.assert_numpy_array_equal

we never directly use numpy comparison routines

the linter will fail if it sees np.testing fyi

assert Interval(1, 3, closed='both').covers(Interval(1, 3, closed='left'))
assert Interval(1, 3, closed='both').covers(Interval(1, 3, closed='both'))

idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for clarity, add closed='left' or closed='right' here? (just so I don't need to remember the default

idx2 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='left')
idx3 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='both')

assert idx.covers(idx1) == (np.array([0,1,2,2]), np.array([0,1,1,2])) # note: I had to choose an arbitrary ordering. If this test fails, double check the test too...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean the order of the last two entries here? I'm actually OK with this -- let's say that returning indices in lexicographically-sorted order is part of the spec.


# slice of scalar
with pytest.raises(NotImplementedError):
s[0:4] ## not sure what the behvaior should be here.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the rule for indexing with integers in [] is to fall back to positional indexing... but honestly I have no idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, slicing with integers in [] is always* positional, so I think should be here as well

*always = for all types of indexes expect ... ra ra .. floats!

But I am fine with raising a NotImplementedError to start with if this is not yet implemented correctly, but it seems this is already working on master:

In [33]: df = pd.DataFrame(['a', 'b', 'c'], columns=['col'], 
    ...:           index=pd.IntervalIndex.from_tuples([(11, 13), (16, 17), (14, 15)], closed='both'))
    ...: 

In [34]: df
Out[34]: 
         col
[11, 13]   a
[16, 17]   b
[14, 15]   c

In [35]: df[:2]
Out[35]: 
         col
[11, 13]   a
[16, 17]   b

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean expect or except?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you're suggesting that df[:2] and df[:2.0] have very different behaviors? This might be a bad idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might indeed be a bad idea .. :-) But I think the following is probably the most consistent and safe given the current indexing mess/complexity:

  • df[:2] does positional indexing (so similar to df.iloc[:2] as it does for all other types of indexing (apart from float index, which I think we should regard as a bug)
  • disallow df[:2.0] ? If you want label based slicing based on the interval ranges, you can use df.loc[:2.0] (although we still have to decide what the semantics of that should be)

Apart from the integers (first case), also slicing with exact Interval objects would be allowed.

@pytest.mark.xfail(reason="new indexing tests for issue 16316")
def test_non_unique_updated_behavior(self):

# Actually I think we should remove this test? Not sure what exactly it's meant to gauge...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not entire sure. I don't think this test needs to change though -- the existing test looks fine.

# this is confusing to me. I would have done:
# expected = s
# result = s.loc[Interval(1, 3):]
# tm.assert_series_equal(expected, result)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test fails because pandas doesn't support slicing if there is a duplicate key.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem to be fully true. As long as they are still sorted, slicing with duplicates seems to work (at least for this test case):

In [36]: s = pd.Series(range(3), index=[1,1,2])

In [37]: s.loc[1:]
Out[37]: 
1    0
1    1
2    2
dtype: int64

# non-unique
with pytest.raises(ValueError):
s[[Interval(1, 3)]]
# not sure why the behavior for [[]] is different than []...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It goes down a different code path, get_indexer vs get_loc

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This currently fails (both for [[]] and .loc[[]]), but shouldn't both just work? (in that case, I would make the test test the correct behaviour, it is marked as xfail anyhow)

@shoyer
Copy link
Member

shoyer commented May 26, 2017 via email

@alexlenail
Copy link
Contributor Author

@shoyer slice locs is a funky method. It seems special-cased when the index is monotonically increasing or decreasing -- is that right?

Thanks for your review by the way! I fixed some stuff up, I think it's mostly ready for another look.

I'm particularly interested in hearing:

  • should tests be moved?
  • should tests be split?
  • should some tests be reduced because their functionality is already being tested elsewhere (e.g. overlaps & covers deferring to get_loc)
  • Are some tests missing? In particular some of the integration tests in indexing might need new equivalents under the "updated" regime, but I'm not totally sure.

Finally, I think (but am not totally sure) I need to take a long look at slice_locs and write some tests for that. I'll take a look at that later today.

@alexlenail
Copy link
Contributor Author

@shoyer I've taken another quick pass, but I'm not entirely sure what to do for slicing.

Would you take a quick look and answer the questions I posted above as well?

@shoyer
Copy link
Member

shoyer commented Jun 6, 2017

@shoyer slice locs is a funky method. It seems special-cased when the index is monotonically increasing or decreasing -- is that right?

Yes, correct.

should some tests be reduced because their functionality is already being tested elsewhere (e.g. overlaps & covers deferring to get_loc)

At least in this case, I would still test these separately.

More detailed comments to follow after I look at your changes in detail...

Copy link
Member

@shoyer shoyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next time, hold off on rebasing until the end. Otherwise rebasing breaks GitHub so I can't see what has changed since my last review :(

idx2 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='left')
idx3 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='both')

tm.assert_numpy_array_equal(idx.covers(idx1), (np.array([0,1,2,2]), np.array([0,1,1,2]))) # note: assert_numpy_array_equal is the wrong thing to call here, since we're testing for equality with a tuple of np arrays
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in that case, use tuple unpacking and two calls to tm.assert_numpy_array_equal

Copy link
Contributor Author

@alexlenail alexlenail Jun 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shoyer or perhaps we should add a method to tm , or just a test method to this file/class?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not :).

It would also be fine to cast the result to a numpy array, e.g., np.array(idx.covers(idx1)).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you actually want to write this comparison like

lidx, ridx = idx.covers(idx1)
tm.asssert_numpy_array_equal(lidx, ....)
tm.asssert_numpy_array_equal(ridx, ....)

or if that gets cumbersome, you can write a little helper

def compare(result, expected):
    lidx, ridx = result
    lidx_expected, ridx_expected = expected

    tm.assert_numpy_array_equal(lidx, lidx_expected)
    tm.assert_numpy_array_equal(ridx, ridx_expected)

and call like

compare(idx.covers, (np....., np.....))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

@@ -491,6 +642,206 @@ def testcontains(self):
assert not i.contains(20)
assert not i.contains(-20)

# Why are there two tests called test contains? this should be cleared up a little, no?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed

@pytest.mark.xfail(reason="new indexing tests for issue 16316")
def test_get_indexer_subintervals_updated_behavior(self):

# target = IntervalIndex.from_breaks(np.linspace(0, 2, 5))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure what the idea is with these commented out lines?

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally looks ok. need to fix the xfails and then get passing.

from __future__ import division

import pytest
import numpy as np
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no literally add that with a nice xfail message.

I want this to skip this entire module for now, rather than showing a skip for each test. This just pollutes the xfail output (which is already getting annoying large).

from __future__ import division

import pytest
import numpy as np
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if you add the xfail up top, then you can remove all of the xfails on individual functions.


from pandas import Series, IntervalIndex, Interval
import pandas.util.testing as tm

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same deal here, skip the entire module for now and remove the xfails on individual tests.

@pep8speaks
Copy link

Hello @zfrenchee! Thanks for updating the PR.

Line 11:1: E302 expected 2 blank lines, found 1
Line 173:80: E501 line too long (87 > 79 characters)
Line 184:80: E501 line too long (83 > 79 characters)
Line 185:80: E501 line too long (84 > 79 characters)
Line 186:80: E501 line too long (84 > 79 characters)
Line 187:80: E501 line too long (89 > 79 characters)
Line 197:80: E501 line too long (85 > 79 characters)
Line 198:80: E501 line too long (87 > 79 characters)
Line 199:80: E501 line too long (91 > 79 characters)
Line 208:80: E501 line too long (89 > 79 characters)
Line 209:80: E501 line too long (102 > 79 characters)
Line 210:80: E501 line too long (93 > 79 characters)
Line 222:80: E501 line too long (85 > 79 characters)
Line 224:21: E126 continuation line over-indented for hanging indent
Line 235:80: E501 line too long (102 > 79 characters)
Line 243:80: E501 line too long (89 > 79 characters)
Line 245:21: E126 continuation line over-indented for hanging indent
Line 252:80: E501 line too long (104 > 79 characters)

Line 8:1: E302 expected 2 blank lines, found 1

@alexlenail
Copy link
Contributor Author

@jreback done. What next?

@jreback
Copy link
Contributor

jreback commented Dec 21, 2017

ping when green

@pep8speaks
Copy link

Hello @zfrenchee! Thanks for updating the PR.

Line 11:1: E302 expected 2 blank lines, found 1
Line 175:61: E127 continuation line over-indented for visual indent
Line 190:63: E127 continuation line over-indented for visual indent
Line 216:47: E128 continuation line under-indented for visual indent
Line 218:63: E128 continuation line under-indented for visual indent
Line 233:21: E126 continuation line over-indented for hanging indent
Line 245:56: E128 continuation line under-indented for visual indent
Line 253:80: E501 line too long (89 > 79 characters)
Line 255:21: E126 continuation line over-indented for hanging indent
Line 263:56: E128 continuation line under-indented for visual indent

@pep8speaks
Copy link

Hello @zfrenchee! Thanks for updating the PR.

Line 11:1: E302 expected 2 blank lines, found 1
Line 200:9: E128 continuation line under-indented for visual indent
Line 202:9: E128 continuation line under-indented for visual indent
Line 214:9: E128 continuation line under-indented for visual indent
Line 216:9: E128 continuation line under-indented for visual indent
Line 218:80: E501 line too long (80 > 79 characters)
Line 231:9: E128 continuation line under-indented for visual indent
Line 233:21: E126 continuation line over-indented for hanging indent
Line 245:53: E128 continuation line under-indented for visual indent
Line 254:9: E128 continuation line under-indented for visual indent
Line 256:21: E126 continuation line over-indented for hanging indent
Line 264:56: E128 continuation line under-indented for visual indent

@jreback
Copy link
Contributor

jreback commented Dec 21, 2017

you know that

git diff upstream/master --name-only -- '*.py' | flake8 --diff

checks pep FYI (this is from the top of the PR)
also make lint-diff is the same

@alexlenail
Copy link
Contributor Author

@jreback my local pep isn't respecting the 80 char limit, when I autoformat the file, which is why I keep using this one to check. We have different versions / configs for pep seems like.

@pep8speaks
Copy link

Hello @zfrenchee! Thanks for updating the PR.

Line 201:9: E128 continuation line under-indented for visual indent
Line 203:9: E128 continuation line under-indented for visual indent
Line 215:9: E128 continuation line under-indented for visual indent
Line 217:9: E128 continuation line under-indented for visual indent
Line 219:80: E501 line too long (80 > 79 characters)
Line 232:9: E128 continuation line under-indented for visual indent
Line 234:21: E126 continuation line over-indented for hanging indent
Line 246:53: E128 continuation line under-indented for visual indent
Line 255:9: E128 continuation line under-indented for visual indent
Line 257:21: E126 continuation line over-indented for hanging indent
Line 265:56: E128 continuation line under-indented for visual indent

@pep8speaks
Copy link

Hello @zfrenchee! Thanks for updating the PR.

Line 201:9: E128 continuation line under-indented for visual indent
Line 203:9: E128 continuation line under-indented for visual indent
Line 215:9: E128 continuation line under-indented for visual indent
Line 217:9: E128 continuation line under-indented for visual indent
Line 219:61: E128 continuation line under-indented for visual indent
Line 232:9: E128 continuation line under-indented for visual indent
Line 234:21: E126 continuation line over-indented for hanging indent
Line 246:53: E128 continuation line under-indented for visual indent
Line 255:9: E128 continuation line under-indented for visual indent
Line 257:21: E126 continuation line over-indented for hanging indent
Line 265:56: E128 continuation line under-indented for visual indent

@pep8speaks
Copy link

Hello @zfrenchee! Thanks for updating the PR.

Line 201:9: E128 continuation line under-indented for visual indent
Line 203:9: E128 continuation line under-indented for visual indent
Line 215:9: E128 continuation line under-indented for visual indent
Line 217:9: E128 continuation line under-indented for visual indent
Line 219:61: E128 continuation line under-indented for visual indent
Line 232:9: E128 continuation line under-indented for visual indent
Line 246:53: E128 continuation line under-indented for visual indent
Line 255:9: E128 continuation line under-indented for visual indent
Line 263:56: E128 continuation line under-indented for visual indent

@alexlenail
Copy link
Contributor Author

@jreback green. Just a few linting issues left, which I don't know how to resolve (see above)

@jreback
Copy link
Contributor

jreback commented Dec 23, 2017

ok I pushed some fixes. ping on green.

@jreback jreback added this to the 0.23.0 milestone Dec 23, 2017
@alexlenail
Copy link
Contributor Author

@jreback green

@jreback jreback merged commit a9f82df into pandas-dev:master Dec 28, 2017
@jreback
Copy link
Contributor

jreback commented Dec 28, 2017

thanks @zfrenchee took a while, but glad we got this in!

next up......patches!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Interval Interval data type Testing pandas testing functions or related to the test suite
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants