File tree 3 files changed +23
-12
lines changed
3 files changed +23
-12
lines changed Original file line number Diff line number Diff line change @@ -737,6 +737,7 @@ Interval
737
737
^^^^^^^^
738
738
- :meth: `IntervalIndex.get_indexer ` and :meth: `IntervalIndex.get_indexer_nonunique ` raising if ``target `` is read-only array (:issue: `53703 `)
739
739
- Bug in :class: `IntervalDtype ` where the object could be kept alive when deleted (:issue: `54184 `)
740
+ - Bug in :func: `interval_range ` where a float ``step `` would produce incorrect intervals from floating point artifacts (:issue: `54477 `)
740
741
741
742
Indexing
742
743
^^^^^^^^
Original file line number Diff line number Diff line change @@ -1121,19 +1121,19 @@ def interval_range(
1121
1121
breaks : np .ndarray | TimedeltaIndex | DatetimeIndex
1122
1122
1123
1123
if is_number (endpoint ):
1124
- # force consistency between start/end/freq (lower end if freq skips it)
1125
1124
if com .all_not_none (start , end , freq ):
1126
- end -= (end - start ) % freq
1127
-
1128
- # compute the period/start/end if unspecified (at most one)
1129
- if periods is None :
1130
- periods = int ((end - start ) // freq ) + 1
1131
- elif start is None :
1132
- start = end - (periods - 1 ) * freq
1133
- elif end is None :
1134
- end = start + (periods - 1 ) * freq
1135
-
1136
- breaks = np .linspace (start , end , periods )
1125
+ # 0.1 ensures we capture end
1126
+ breaks = np .arange (start , end + (freq * 0.1 ), freq )
1127
+ else :
1128
+ # compute the period/start/end if unspecified (at most one)
1129
+ if periods is None :
1130
+ periods = int ((end - start ) // freq ) + 1
1131
+ elif start is None :
1132
+ start = end - (periods - 1 ) * freq
1133
+ elif end is None :
1134
+ end = start + (periods - 1 ) * freq
1135
+
1136
+ breaks = np .linspace (start , end , periods )
1137
1137
if all (is_integer (x ) for x in com .not_none (start , end , freq )):
1138
1138
# np.linspace always produces float output
1139
1139
Original file line number Diff line number Diff line change @@ -353,3 +353,13 @@ def test_errors(self):
353
353
msg = "Start and end cannot both be tz-aware with different timezones"
354
354
with pytest .raises (TypeError , match = msg ):
355
355
interval_range (start = start , end = end )
356
+
357
+ def test_float_freq (self ):
358
+ # GH 54477
359
+ result = interval_range (0 , 1 , freq = 0.1 )
360
+ expected = IntervalIndex .from_breaks ([0 + 0.1 * n for n in range (11 )])
361
+ tm .assert_index_equal (result , expected )
362
+
363
+ result = interval_range (0 , 1 , freq = 0.6 )
364
+ expected = IntervalIndex .from_breaks ([0 , 0.6 ])
365
+ tm .assert_index_equal (result , expected )
You can’t perform that action at this time.
0 commit comments