Skip to content

Commit be90d49

Browse files
authored
BUG: Fix invalid truncation in interval_range (pandas-dev#21162)
1 parent cd04471 commit be90d49

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

doc/source/whatsnew/v0.23.1.txt

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ Indexing
7777
^^^^^^^^
7878

7979
- Bug in :meth:`Series.reset_index` where appropriate error was not raised with an invalid level name (:issue:`20925`)
80+
- Bug in :func:`interval_range` when ``start``/``periods`` or ``end``/``periods`` are specified with float ``start`` or ``end`` (:issue:`21161`)
8081
-
8182

8283
I/O

pandas/core/indexes/interval.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,10 @@ def interval_range(start=None, end=None, periods=None, freq=None,
15721572
periods += 1
15731573

15741574
if is_number(endpoint):
1575+
# force consistency between start/end/freq (lower end if freq skips it)
1576+
if com._all_not_none(start, end, freq):
1577+
end -= (end - start) % freq
1578+
15751579
# compute the period/start/end if unspecified (at most one)
15761580
if periods is None:
15771581
periods = int((end - start) // freq) + 1
@@ -1580,10 +1584,6 @@ def interval_range(start=None, end=None, periods=None, freq=None,
15801584
elif end is None:
15811585
end = start + (periods - 1) * freq
15821586

1583-
# force end to be consistent with freq (lower if freq skips end)
1584-
if freq is not None:
1585-
end -= end % freq
1586-
15871587
breaks = np.linspace(start, end, periods)
15881588
if all(is_integer(x) for x in com._not_none(start, end, freq)):
15891589
# np.linspace always produces float output

pandas/tests/indexes/interval/test_interval_range.py

+18
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ def test_constructor_timedelta(self, closed, name, freq, periods):
110110

111111
@pytest.mark.parametrize('start, end, freq, expected_endpoint', [
112112
(0, 10, 3, 9),
113+
(0, 10, 1.5, 9),
114+
(0.5, 10, 3, 9.5),
113115
(Timedelta('0D'), Timedelta('10D'), '2D4H', Timedelta('8D16H')),
114116
(Timestamp('2018-01-01'),
115117
Timestamp('2018-02-09'),
@@ -125,6 +127,22 @@ def test_early_truncation(self, start, end, freq, expected_endpoint):
125127
result_endpoint = result.right[-1]
126128
assert result_endpoint == expected_endpoint
127129

130+
@pytest.mark.parametrize('start, end, freq', [
131+
(0.5, None, None),
132+
(None, 4.5, None),
133+
(0.5, None, 1.5),
134+
(None, 6.5, 1.5)])
135+
def test_no_invalid_float_truncation(self, start, end, freq):
136+
# GH 21161
137+
if freq is None:
138+
breaks = [0.5, 1.5, 2.5, 3.5, 4.5]
139+
else:
140+
breaks = [0.5, 2.0, 3.5, 5.0, 6.5]
141+
expected = IntervalIndex.from_breaks(breaks)
142+
143+
result = interval_range(start=start, end=end, periods=4, freq=freq)
144+
tm.assert_index_equal(result, expected)
145+
128146
@pytest.mark.parametrize('start, mid, end', [
129147
(Timestamp('2018-03-10', tz='US/Eastern'),
130148
Timestamp('2018-03-10 23:30:00', tz='US/Eastern'),

0 commit comments

Comments
 (0)