def _generate_range(cls, start, end, periods, freq, fields): field_count = com._count_not_none(*fields) if com._count_not_none(start, end) > 0: if field_count > 0: raise ValueError("Can either instantiate from fields " "or endpoints, but not both") subarr, freq = _get_ordinal_range(start, end, periods, freq) elif field_count > 0: y, mth, q, d, h, minute, s = fields subarr, freq = _range_from_fields( year=y, month=mth, quarter=q, day=d, hour=h, minute=minute, second=s, freq=freq ) else: raise ValueError("Not enough parameters to construct " "Period range") return subarr, freq
def _generate_regular_range(start, end, periods, offset): if com._count_not_none(start, end, periods) < 2: raise ValueError("Must specify two of start, end, or periods") if isinstance(offset, Tick): stride = offset.nanos if periods is None: b = Timestamp(start).value e = Timestamp(end).value e += stride - e % stride elif start is not None: b = Timestamp(start).value e = b + periods * stride elif end is not None: e = Timestamp(end).value + stride b = e - periods * stride else: raise NotImplementedError data = np.arange(b, e, stride, dtype=np.int64) data = data.view("M8[ns]") else: xdr = generate_range(start=start, end=end, periods=periods, offset=offset) data = np.array(list(xdr), dtype="M8[ns]") return data
def _get_ordinal_range(start, end, periods, freq): if com._count_not_none(start, end, periods) < 2: raise ValueError('Must specify 2 of start, end, periods') if start is not None: start = Period(start, freq) if end is not None: end = Period(end, freq) is_start_per = isinstance(start, Period) is_end_per = isinstance(end, Period) if is_start_per and is_end_per and (start.freq != end.freq): raise ValueError('Start and end must have same freq') if freq is None: if is_start_per: freq = start.freq elif is_end_per: freq = end.freq else: # pragma: no cover raise ValueError('Could not infer freq from start/end') if periods is not None: if start is None: data = np.arange(end.ordinal - periods + 1, end.ordinal + 1, dtype=np.int64) else: data = np.arange(start.ordinal, start.ordinal + periods, dtype=np.int64) else: data = np.arange(start.ordinal, end.ordinal+1, dtype=np.int64) return data, freq
def _needs_reindex_multi(self, axes, method, level): # only allowing multi-index on Panel (and not > dims) return ( method is None and not self._is_mixed_type and self._AXIS_LEN <= 3 and com._count_not_none(*axes.values()) == 3 )
def period_range(start=None, end=None, periods=None, freq='D', name=None): """ Return a fixed frequency PeriodIndex, with day (calendar) as the default frequency Parameters ---------- start : string or period-like, default None Left bound for generating periods end : string or period-like, default None Right bound for generating periods periods : integer, default None Number of periods to generate freq : string or DateOffset, default 'D' (calendar daily) Frequency alias name : string, default None Name of the resulting PeriodIndex Notes ----- Of the three parameters: ``start``, ``end``, and ``periods``, exactly two must be specified. To learn more about the frequency strings, please see `this link <http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases>`__. Returns ------- prng : PeriodIndex Examples -------- >>> pd.period_range(start='2017-01-01', end='2018-01-01', freq='M') PeriodIndex(['2017-01', '2017-02', '2017-03', '2017-04', '2017-05', '2017-06', '2017-06', '2017-07', '2017-08', '2017-09', '2017-10', '2017-11', '2017-12', '2018-01'], dtype='period[M]', freq='M') If ``start`` or ``end`` are ``Period`` objects, they will be used as anchor endpoints for a ``PeriodIndex`` with frequency matching that of the ``period_range`` constructor. >>> pd.period_range(start=pd.Period('2017Q1', freq='Q'), ... end=pd.Period('2017Q2', freq='Q'), freq='M') PeriodIndex(['2017-03', '2017-04', '2017-05', '2017-06'], dtype='period[M]', freq='M') """ if com._count_not_none(start, end, periods) != 2: raise ValueError('Of the three parameters: start, end, and periods, ' 'exactly two must be specified') return PeriodIndex(start=start, end=end, periods=periods, freq=freq, name=name)
def _generate_range(cls, start, end, periods, freq, fields): field_count = len(fields) if com._count_not_none(start, end) > 0: if field_count > 0: raise ValueError("Can either instantiate from fields " "or endpoints, but not both") subarr, freq = _get_ordinal_range(start, end, periods, freq) elif field_count > 0: subarr, freq = _range_from_fields(freq=freq, **fields) else: raise ValueError("Not enough parameters to construct " "Period range") return subarr, freq
def _generate_range(cls, start, end, periods, freq, fields): if freq is not None: freq = Period._maybe_convert_freq(freq) field_count = len(fields) if com._count_not_none(start, end) > 0: if field_count > 0: raise ValueError('Can either instantiate from fields ' 'or endpoints, but not both') subarr, freq = _get_ordinal_range(start, end, periods, freq) elif field_count > 0: subarr, freq = _range_from_fields(freq=freq, **fields) else: raise ValueError('Not enough parameters to construct ' 'Period range') return subarr, freq
def _generate(cls, start, end, periods, name, offset, tz=None, normalize=False): _normalized = True if start is not None: start = Timestamp(start) if normalize: start = normalize_date(start) _normalized = True else: _normalized = _normalized and start.time() == _midnight if end is not None: end = Timestamp(end) if normalize: end = normalize_date(end) _normalized = True else: _normalized = _normalized and end.time() == _midnight start, end, tz = tools._figure_out_timezone(start, end, tz) if com._count_not_none(start, end, periods) < 2: raise ValueError('Must specify two of start, end, or periods') if (offset._should_cache() and not (offset._normalize_cache and not _normalized) and _naive_in_cache_range(start, end)): index = cls._cached_range(start, end, periods=periods, offset=offset, name=name) else: index = _generate_regular_range(start, end, periods, offset) if tz is not None: # Convert local to UTC ints = index.view('i8', type=np.ndarray) index = lib.tz_localize_to_utc(ints, tz) index = index.view(_NS_DTYPE) index = index.view(cls) index.name = name index.offset = offset index.tz = tz return index
def reindex(self, major=None, items=None, minor=None, method=None, major_axis=None, minor_axis=None, copy=True): """ Conform panel to new axis or axes Parameters ---------- major : Index or sequence, default None Can also use 'major_axis' keyword items : Index or sequence, default None minor : Index or sequence, default None Can also use 'minor_axis' keyword method : {'backfill', 'bfill', 'pad', 'ffill', None}, default None Method to use for filling holes in reindexed Series pad / ffill: propagate last valid observation forward to next valid backfill / bfill: use NEXT valid observation to fill gap copy : boolean, default True Return a new object, even if the passed indexes are the same Returns ------- Panel (new object) """ result = self major = _mut_exclusive(major, major_axis) minor = _mut_exclusive(minor, minor_axis) if (method is None and not self._is_mixed_type and com._count_not_none(items, major, minor) == 3): return self._reindex_multi(items, major, minor) if major is not None: result = result._reindex_axis(major, method, 1, copy) if minor is not None: result = result._reindex_axis(minor, method, 2, copy) if items is not None: result = result._reindex_axis(items, method, 0, copy) if result is self and copy: raise ValueError('Must specify at least one axis') return result
def _get_ordinal_range(start, end, periods, freq, mult=1): if com._count_not_none(start, end, periods) < 2: raise ValueError('Must specify 2 of start, end, periods') if freq is not None: _, mult = _gfc(freq) if start is not None: start = Period(start, freq) if end is not None: end = Period(end, freq) is_start_per = isinstance(start, Period) is_end_per = isinstance(end, Period) if is_start_per and is_end_per and start.freq != end.freq: raise ValueError('Start and end must have same freq') if ((is_start_per and start.ordinal == tslib.iNaT) or (is_end_per and end.ordinal == tslib.iNaT)): raise ValueError('Start and end must not be NaT') if freq is None: if is_start_per: freq = start.freq elif is_end_per: freq = end.freq else: # pragma: no cover raise ValueError('Could not infer freq from start/end') if periods is not None: periods = periods * mult if start is None: data = np.arange(end.ordinal - periods + mult, end.ordinal + 1, mult, dtype=np.int64) else: data = np.arange(start.ordinal, start.ordinal + periods, mult, dtype=np.int64) else: data = np.arange(start.ordinal, end.ordinal + 1, mult, dtype=np.int64) return data, freq
def get_jstock(code, freq='D', start=None, end=None, periods=None): """get Japanese stock data using jsm Usage: `get_jstock(6502)` To get TOSHIBA daily from today back to 30days except holiday. `get_jstock(6502, 'W', start=pd.Timestamp('2016'), end=pd.Timestamp('2017'))` To get TOSHIBA weekly from 2016-01-01 to 2017-01-01. `get_jstock(6502, end=pd.Timestamp('20170201'), periods=50)` To get TOSHIBA daily from 2017-02-01 back to 50days except holiday. `get_jstock(6502, 'M', start='first', end='last')` To get TOSHIBA monthly from 2000-01-01 (the date of start recording) to today. """ # Default args if com._count_not_none(start, end, periods) == 0: # All of args is None end, periods = 'last', 30 # Switch frequency Dayly, Weekly or Monthly freq_dict = {'D': jsm.DAILY, 'W': jsm.WEEKLY, 'M': jsm.MONTHLY} # 'first' means the start of recording date if start == 'first': data = jsm.Quotes().get_historical_prices(code, range_type=freq_dict[freq], all=True) start = [i.date for i in data][-1] else: data = None # Temporaly defined # 'last' means last weekday (or today) if end == 'last': end = pd.datetime.today() # Return "start" and "end" start, end = (x.date() if hasattr(x, 'date') else x for x in set_span(start, end, periods, freq)) print('Get data from {} to {}'.format(start, end)) data = jsm.Quotes().get_historical_prices( code, range_type=freq_dict[freq], start_date=start, end_date=end) if not data else data df = _convert_dataframe(data) return df[start:end]
def _get_ordinal_range(start, end, periods, freq, mult=1): if com._count_not_none(start, end, periods) != 2: raise ValueError('Of the three parameters: start, end, and periods, ' 'exactly two must be specified') if freq is not None: _, mult = _gfc(freq) if start is not None: start = Period(start, freq) if end is not None: end = Period(end, freq) is_start_per = isinstance(start, Period) is_end_per = isinstance(end, Period) if is_start_per and is_end_per and start.freq != end.freq: raise ValueError('start and end must have same freq') if (start is tslib.NaT or end is tslib.NaT): raise ValueError('start and end must not be NaT') if freq is None: if is_start_per: freq = start.freq elif is_end_per: freq = end.freq else: # pragma: no cover raise ValueError('Could not infer freq from start/end') if periods is not None: periods = periods * mult if start is None: data = np.arange(end.ordinal - periods + mult, end.ordinal + 1, mult, dtype=np.int64) else: data = np.arange(start.ordinal, start.ordinal + periods, mult, dtype=np.int64) else: data = np.arange(start.ordinal, end.ordinal + 1, mult, dtype=np.int64) return data, freq
def _generate(cls, start, end, periods, freq, closed=None, **kwargs): # **kwargs are for compat with TimedeltaIndex, which includes `name` if com._count_not_none(start, end, periods, freq) != 3: raise ValueError('Of the four parameters: start, end, periods, ' 'and freq, exactly three must be specified') if start is not None: start = Timedelta(start) if end is not None: end = Timedelta(end) left_closed = False right_closed = False if start is None and end is None: if closed is not None: raise ValueError("Closed has to be None if not both of start" "and end are defined") if closed is None: left_closed = True right_closed = True elif closed == "left": left_closed = True elif closed == "right": right_closed = True else: raise ValueError("Closed has to be either 'left', 'right' or None") if freq is not None: index = _generate_regular_range(start, end, periods, freq) index = cls._simple_new(index, freq=freq, **kwargs) else: index = np.linspace(start.value, end.value, periods).astype('i8') # TODO: shouldn't we pass `name` here? (via **kwargs) index = cls._simple_new(index, freq=freq) if not left_closed: index = index[1:] if not right_closed: index = index[:-1] return index
def _get_ordinal_range(start, end, periods, freq): if com._count_not_none(start, end, periods) < 2: raise ValueError('Must specify 2 of start, end, periods') start = to_period(start, freq) end = to_period(end, freq) is_start_per = isinstance(start, Period) is_end_per = isinstance(end, Period) if (start is not None and not is_start_per): raise ValueError('Failed to convert %s to period' % start) if (end is not None and not is_end_per): raise ValueError('Failed to convert %s to period' % end) if is_start_per and is_end_per and (start.freq != end.freq): raise ValueError('Start and end must have same freq') if freq is None: if is_start_per: freq = start.freq elif is_end_per: freq = end.freq else: raise ValueError('Could not infer freq from start/end') if periods is not None: if start is None: data = np.arange(end.ordinal - periods + 1, end.ordinal + 1, dtype=np.int64) else: data = np.arange(start.ordinal, start.ordinal + periods, dtype=np.int64) else: if start is None or end is None: msg = 'Must specify both start and end if periods is None' raise ValueError(msg) data = np.arange(start.ordinal, end.ordinal+1, dtype=np.int64) return data, freq
def _generate(cls, start, end, periods, name, freq, closed=None): if com._count_not_none(start, end, periods, freq) != 3: raise ValueError('Of the four parameters: start, end, periods, ' 'and freq, exactly three must be specified') if start is not None: start = Timedelta(start) if end is not None: end = Timedelta(end) left_closed = False right_closed = False if start is None and end is None: if closed is not None: raise ValueError("Closed has to be None if not both of start" "and end are defined") if closed is None: left_closed = True right_closed = True elif closed == "left": left_closed = True elif closed == "right": right_closed = True else: raise ValueError("Closed has to be either 'left', 'right' or None") if freq is not None: index = _generate_regular_range(start, end, periods, freq) index = cls._simple_new(index, name=name, freq=freq) else: index = to_timedelta(np.linspace(start.value, end.value, periods)) if not left_closed: index = index[1:] if not right_closed: index = index[:-1] return index
def _generate(cls, start, end, periods, name, offset, closed=None): if com._count_not_none(start, end, periods) != 2: raise ValueError('Of the three parameters: start, end, and ' 'periods, exactly two must be specified') if start is not None: start = Timedelta(start) if end is not None: end = Timedelta(end) left_closed = False right_closed = False if start is None and end is None: if closed is not None: raise ValueError("Closed has to be None if not both of start" "and end are defined") if closed is None: left_closed = True right_closed = True elif closed == "left": left_closed = True elif closed == "right": right_closed = True else: raise ValueError("Closed has to be either 'left', 'right' or None") index = _generate_regular_range(start, end, periods, offset) index = cls._simple_new(index, name=name, freq=offset) if not left_closed: index = index[1:] if not right_closed: index = index[:-1] return index
def _get_ordinal_range(start, end, periods, freq, mult=1): if com._count_not_none(start, end, periods) < 2: raise ValueError("Must specify 2 of start, end, periods") if freq is not None: _, mult = _gfc(freq) if start is not None: start = Period(start, freq) if end is not None: end = Period(end, freq) is_start_per = isinstance(start, Period) is_end_per = isinstance(end, Period) if is_start_per and is_end_per and start.freq != end.freq: raise ValueError("Start and end must have same freq") if (is_start_per and start.ordinal == tslib.iNaT) or (is_end_per and end.ordinal == tslib.iNaT): raise ValueError("Start and end must not be NaT") if freq is None: if is_start_per: freq = start.freq elif is_end_per: freq = end.freq else: # pragma: no cover raise ValueError("Could not infer freq from start/end") if periods is not None: periods = periods * mult if start is None: data = np.arange(end.ordinal - periods + mult, end.ordinal + 1, mult, dtype=np.int64) else: data = np.arange(start.ordinal, start.ordinal + periods, mult, dtype=np.int64) else: data = np.arange(start.ordinal, end.ordinal + 1, mult, dtype=np.int64) return data, freq
def generate_range(start=None, end=None, periods=None, offset=BDay(), time_rule=None): """ Generates a sequence of dates corresponding to the specified time offset. Similar to dateutil.rrule except uses pandas DateOffset objects to represent time increments Parameters ---------- start : datetime (default None) end : datetime (default None) periods : int, optional Note ---- * This method is faster for generating weekdays than dateutil.rrule * At least two of (start, end, periods) must be specified. * If both start and end are specified, the returned dates will satisfy start <= date <= end. Returns ------- dates : generator object """ if time_rule is not None: from pandas.tseries.frequencies import get_offset offset = get_offset(time_rule) start = to_datetime(start) end = to_datetime(end) if start and not offset.onOffset(start): start = offset.rollforward(start) if end and not offset.onOffset(end): end = offset.rollback(end) if periods is None and end < start: end = None periods = 0 if _count_not_none(start, end, periods) < 2: raise ValueError('Must specify 2 of start, end, periods') if end is None: end = start + (periods - 1) * offset if start is None: start = end - (periods - 1) * offset cur = start next_date = cur while cur <= end: yield cur # faster than cur + offset next_date = offset.apply(cur) if next_date <= cur: raise ValueError('Offset %s did not increment date' % offset) cur = next_date
def interval_range(start=None, end=None, periods=None, freq=None, name=None, closed='right'): """ Return a fixed frequency IntervalIndex Parameters ---------- start : numeric or datetime-like, default None Left bound for generating intervals end : numeric or datetime-like, default None Right bound for generating intervals periods : integer, default None Number of periods to generate freq : numeric, string, or DateOffset, default None The length of each interval. Must be consistent with the type of start and end, e.g. 2 for numeric, or '5H' for datetime-like. Default is 1 for numeric and 'D' (calendar daily) for datetime-like. name : string, default None Name of the resulting IntervalIndex closed : {'left', 'right', 'both', 'neither'}, default 'right' Whether the intervals are closed on the left-side, right-side, both or neither. Notes ----- Of the four parameters ``start``, ``end``, ``periods``, and ``freq``, exactly three must be specified. If ``freq`` is omitted, the resulting ``IntervalIndex`` will have ``periods`` linearly spaced elements between ``start`` and ``end``, inclusively. To learn more about datetime-like frequency strings, please see `this link <http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases>`__. Returns ------- rng : IntervalIndex Examples -------- Numeric ``start`` and ``end`` is supported. >>> pd.interval_range(start=0, end=5) IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]] closed='right', dtype='interval[int64]') Additionally, datetime-like input is also supported. >>> pd.interval_range(start=pd.Timestamp('2017-01-01'), end=pd.Timestamp('2017-01-04')) IntervalIndex([(2017-01-01, 2017-01-02], (2017-01-02, 2017-01-03], (2017-01-03, 2017-01-04]] closed='right', dtype='interval[datetime64[ns]]') The ``freq`` parameter specifies the frequency between the left and right. endpoints of the individual intervals within the ``IntervalIndex``. For numeric ``start`` and ``end``, the frequency must also be numeric. >>> pd.interval_range(start=0, periods=4, freq=1.5) IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]] closed='right', dtype='interval[float64]') Similarly, for datetime-like ``start`` and ``end``, the frequency must be convertible to a DateOffset. >>> pd.interval_range(start=pd.Timestamp('2017-01-01'), periods=3, freq='MS') IntervalIndex([(2017-01-01, 2017-02-01], (2017-02-01, 2017-03-01], (2017-03-01, 2017-04-01]] closed='right', dtype='interval[datetime64[ns]]') Specify ``start``, ``end``, and ``periods``; the frequency is generated automatically (linearly spaced). >>> pd.interval_range(start=0, end=6, periods=4) IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]] closed='right', dtype='interval[float64]') The ``closed`` parameter specifies which endpoints of the individual intervals within the ``IntervalIndex`` are closed. >>> pd.interval_range(end=5, periods=4, closed='both') IntervalIndex([[1, 2], [2, 3], [3, 4], [4, 5]] closed='both', dtype='interval[int64]') See Also -------- IntervalIndex : an Index of intervals that are all closed on the same side. """ start = com._maybe_box_datetimelike(start) end = com._maybe_box_datetimelike(end) endpoint = start if start is not None else end if freq is None and com._any_none(periods, start, end): freq = 1 if is_number(endpoint) else 'D' if com._count_not_none(start, end, periods, freq) != 3: raise ValueError('Of the four parameters: start, end, periods, and ' 'freq, exactly three must be specified') if not _is_valid_endpoint(start): msg = 'start must be numeric or datetime-like, got {start}' raise ValueError(msg.format(start=start)) elif not _is_valid_endpoint(end): msg = 'end must be numeric or datetime-like, got {end}' raise ValueError(msg.format(end=end)) if is_float(periods): periods = int(periods) elif not is_integer(periods) and periods is not None: msg = 'periods must be a number, got {periods}' raise TypeError(msg.format(periods=periods)) if freq is not None and not is_number(freq): try: freq = to_offset(freq) except ValueError: raise ValueError('freq must be numeric or convertible to ' 'DateOffset, got {freq}'.format(freq=freq)) # verify type compatibility if not all([ _is_type_compatible(start, end), _is_type_compatible(start, freq), _is_type_compatible(end, freq) ]): raise TypeError("start, end, freq need to be type compatible") # +1 to convert interval count to breaks count (n breaks = n-1 intervals) if periods is not None: periods += 1 if is_number(endpoint): # force consistency between start/end/freq (lower end if freq skips it) if com._all_not_none(start, end, freq): end -= (end - start) % freq # compute the period/start/end if unspecified (at most one) if periods is None: periods = int((end - start) // freq) + 1 elif start is None: start = end - (periods - 1) * freq elif end is None: end = start + (periods - 1) * freq breaks = np.linspace(start, end, periods) if all(is_integer(x) for x in com._not_none(start, end, freq)): # np.linspace always produces float output breaks = maybe_downcast_to_dtype(breaks, 'int64') else: # delegate to the appropriate range function if isinstance(endpoint, Timestamp): range_func = date_range else: range_func = timedelta_range breaks = range_func(start=start, end=end, periods=periods, freq=freq) return IntervalIndex.from_breaks(breaks, name=name, closed=closed)
def interval_range(start=None, end=None, periods=None, freq=None, name=None, closed='right'): """ Return a fixed frequency IntervalIndex Parameters ---------- start : numeric or datetime-like, default None Left bound for generating intervals end : numeric or datetime-like, default None Right bound for generating intervals periods : integer, default None Number of periods to generate freq : numeric, string, or DateOffset, default None The length of each interval. Must be consistent with the type of start and end, e.g. 2 for numeric, or '5H' for datetime-like. Default is 1 for numeric and 'D' (calendar daily) for datetime-like. name : string, default None Name of the resulting IntervalIndex closed : string, default 'right' options are: 'left', 'right', 'both', 'neither' Notes ----- Of the three parameters: ``start``, ``end``, and ``periods``, exactly two must be specified. Returns ------- rng : IntervalIndex Examples -------- Numeric ``start`` and ``end`` is supported. >>> pd.interval_range(start=0, end=5) IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]] closed='right', dtype='interval[int64]') Additionally, datetime-like input is also supported. >>> pd.interval_range(start=pd.Timestamp('2017-01-01'), end=pd.Timestamp('2017-01-04')) IntervalIndex([(2017-01-01, 2017-01-02], (2017-01-02, 2017-01-03], (2017-01-03, 2017-01-04]] closed='right', dtype='interval[datetime64[ns]]') The ``freq`` parameter specifies the frequency between the left and right. endpoints of the individual intervals within the ``IntervalIndex``. For numeric ``start`` and ``end``, the frequency must also be numeric. >>> pd.interval_range(start=0, periods=4, freq=1.5) IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]] closed='right', dtype='interval[float64]') Similarly, for datetime-like ``start`` and ``end``, the frequency must be convertible to a DateOffset. >>> pd.interval_range(start=pd.Timestamp('2017-01-01'), periods=3, freq='MS') IntervalIndex([(2017-01-01, 2017-02-01], (2017-02-01, 2017-03-01], (2017-03-01, 2017-04-01]] closed='right', dtype='interval[datetime64[ns]]') The ``closed`` parameter specifies which endpoints of the individual intervals within the ``IntervalIndex`` are closed. >>> pd.interval_range(end=5, periods=4, closed='both') IntervalIndex([[1, 2], [2, 3], [3, 4], [4, 5]] closed='both', dtype='interval[int64]') See Also -------- IntervalIndex : an Index of intervals that are all closed on the same side. """ if _count_not_none(start, end, periods) != 2: raise ValueError('Of the three parameters: start, end, and periods, ' 'exactly two must be specified') start = _maybe_box_datetimelike(start) end = _maybe_box_datetimelike(end) endpoint = next(_not_none(start, end)) if not _is_valid_endpoint(start): msg = 'start must be numeric or datetime-like, got {start}' raise ValueError(msg.format(start=start)) if not _is_valid_endpoint(end): msg = 'end must be numeric or datetime-like, got {end}' raise ValueError(msg.format(end=end)) if is_float(periods): periods = int(periods) elif not is_integer(periods) and periods is not None: msg = 'periods must be a number, got {periods}' raise TypeError(msg.format(periods=periods)) freq = freq or (1 if is_number(endpoint) else 'D') if not is_number(freq): try: freq = to_offset(freq) except ValueError: raise ValueError('freq must be numeric or convertible to ' 'DateOffset, got {freq}'.format(freq=freq)) # verify type compatibility if not all([_is_type_compatible(start, end), _is_type_compatible(start, freq), _is_type_compatible(end, freq)]): raise TypeError("start, end, freq need to be type compatible") if is_number(endpoint): if periods is None: periods = int((end - start) // freq) if start is None: start = end - periods * freq # force end to be consistent with freq (lower if freq skips over end) end = start + periods * freq # end + freq for inclusive endpoint breaks = np.arange(start, end + freq, freq) elif isinstance(endpoint, Timestamp): # add one to account for interval endpoints (n breaks = n-1 intervals) if periods is not None: periods += 1 breaks = date_range(start=start, end=end, periods=periods, freq=freq) else: # add one to account for interval endpoints (n breaks = n-1 intervals) if periods is not None: periods += 1 breaks = timedelta_range(start=start, end=end, periods=periods, freq=freq) return IntervalIndex.from_breaks(breaks, name=name, closed=closed)
def plot(self, start_view=None, end_view=None, periods_view=None, shift=None, start_plot=None, end_plot=None, periods_plot=None, showgrid=True, validate=False, **kwargs): """Retrun plotly candle chart graph USAGE: `fx.plot()` * Args: * start, end: 最初と最後のdatetime, 'first'でindexの最初、'last'でindexの最後 * periods: 足の本数 > **start, end, periods合わせて2つの引数が必要** * shift: shiftの本数の足だけ右側に空白 * Return: グラフデータとレイアウト(plotly.graph_objs.graph_objs.Figure) """ # ---------Set "plot_dataframe"---------- # Default Args if com._count_not_none(start_plot, end_plot, periods_plot) == 0: end_plot = 'last' periods_plot = 300 # first/last start_plot = self.stock_dataframe.index[ 0] if start_plot == 'first' else start_plot end_plot = self.stock_dataframe.index[ -1] if end_plot == 'last' else end_plot # Set "plot_dataframe" start_plot, end_plot = set_span(start_plot, end_plot, periods_plot, self.freq) plot_dataframe = self.stock_dataframe.loc[start_plot:end_plot] self._fig = FF.create_candlestick(plot_dataframe.open, plot_dataframe.high, plot_dataframe.low, plot_dataframe.close, dates=plot_dataframe.index) # ---------Set "view"---------- # Default Args if com._count_not_none(start_view, end_view, periods_view) == 0: end_view = 'last' periods_view = 50 # first/last start_view = plot_dataframe.index[ 0] if start_view == 'first' else start_view end_view = plot_dataframe.index[-1] if end_view == 'last' else end_view # Set "view" start_view, end_view = set_span(start_view, end_view, periods_view, self.freq) end_view = set_span(start=end_view, periods=shift, freq=self.freq)[-1] if shift else end_view view = list(to_unix_time(start_view, end_view)) # ---------Plot graph---------- self._fig['layout'].update(xaxis={ 'showgrid': showgrid, 'range': view }, yaxis={"autorange": True}) return self._fig
def interval_range(start=None, end=None, periods=None, freq=None, name=None, closed='right'): """ Return a fixed frequency IntervalIndex Parameters ---------- start : numeric or datetime-like, default None Left bound for generating intervals end : numeric or datetime-like, default None Right bound for generating intervals periods : integer, default None Number of periods to generate freq : numeric, string, or DateOffset, default None The length of each interval. Must be consistent with the type of start and end, e.g. 2 for numeric, or '5H' for datetime-like. Default is 1 for numeric and 'D' (calendar daily) for datetime-like. name : string, default None Name of the resulting IntervalIndex closed : {'left', 'right', 'both', 'neither'}, default 'right' Whether the intervals are closed on the left-side, right-side, both or neither. Notes ----- Of the four parameters ``start``, ``end``, ``periods``, and ``freq``, exactly three must be specified. If ``freq`` is omitted, the resulting ``IntervalIndex`` will have ``periods`` linearly spaced elements between ``start`` and ``end``, inclusively. To learn more about datetime-like frequency strings, please see `this link <http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases>`__. Returns ------- rng : IntervalIndex Examples -------- Numeric ``start`` and ``end`` is supported. >>> pd.interval_range(start=0, end=5) IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]] closed='right', dtype='interval[int64]') Additionally, datetime-like input is also supported. >>> pd.interval_range(start=pd.Timestamp('2017-01-01'), end=pd.Timestamp('2017-01-04')) IntervalIndex([(2017-01-01, 2017-01-02], (2017-01-02, 2017-01-03], (2017-01-03, 2017-01-04]] closed='right', dtype='interval[datetime64[ns]]') The ``freq`` parameter specifies the frequency between the left and right. endpoints of the individual intervals within the ``IntervalIndex``. For numeric ``start`` and ``end``, the frequency must also be numeric. >>> pd.interval_range(start=0, periods=4, freq=1.5) IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]] closed='right', dtype='interval[float64]') Similarly, for datetime-like ``start`` and ``end``, the frequency must be convertible to a DateOffset. >>> pd.interval_range(start=pd.Timestamp('2017-01-01'), periods=3, freq='MS') IntervalIndex([(2017-01-01, 2017-02-01], (2017-02-01, 2017-03-01], (2017-03-01, 2017-04-01]] closed='right', dtype='interval[datetime64[ns]]') Specify ``start``, ``end``, and ``periods``; the frequency is generated automatically (linearly spaced). >>> pd.interval_range(start=0, end=6, periods=4) IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]] closed='right', dtype='interval[float64]') The ``closed`` parameter specifies which endpoints of the individual intervals within the ``IntervalIndex`` are closed. >>> pd.interval_range(end=5, periods=4, closed='both') IntervalIndex([[1, 2], [2, 3], [3, 4], [4, 5]] closed='both', dtype='interval[int64]') See Also -------- IntervalIndex : an Index of intervals that are all closed on the same side. """ start = com._maybe_box_datetimelike(start) end = com._maybe_box_datetimelike(end) endpoint = start if start is not None else end if freq is None and com._any_none(periods, start, end): freq = 1 if is_number(endpoint) else 'D' if com._count_not_none(start, end, periods, freq) != 3: raise ValueError('Of the four parameters: start, end, periods, and ' 'freq, exactly three must be specified') if not _is_valid_endpoint(start): msg = 'start must be numeric or datetime-like, got {start}' raise ValueError(msg.format(start=start)) elif not _is_valid_endpoint(end): msg = 'end must be numeric or datetime-like, got {end}' raise ValueError(msg.format(end=end)) if is_float(periods): periods = int(periods) elif not is_integer(periods) and periods is not None: msg = 'periods must be a number, got {periods}' raise TypeError(msg.format(periods=periods)) if freq is not None and not is_number(freq): try: freq = to_offset(freq) except ValueError: raise ValueError('freq must be numeric or convertible to ' 'DateOffset, got {freq}'.format(freq=freq)) # verify type compatibility if not all([_is_type_compatible(start, end), _is_type_compatible(start, freq), _is_type_compatible(end, freq)]): raise TypeError("start, end, freq need to be type compatible") # +1 to convert interval count to breaks count (n breaks = n-1 intervals) if periods is not None: periods += 1 if is_number(endpoint): # force consistency between start/end/freq (lower end if freq skips it) if com._all_not_none(start, end, freq): end -= (end - start) % freq # compute the period/start/end if unspecified (at most one) if periods is None: periods = int((end - start) // freq) + 1 elif start is None: start = end - (periods - 1) * freq elif end is None: end = start + (periods - 1) * freq breaks = np.linspace(start, end, periods) if all(is_integer(x) for x in com._not_none(start, end, freq)): # np.linspace always produces float output breaks = maybe_downcast_to_dtype(breaks, 'int64') else: # delegate to the appropriate range function if isinstance(endpoint, Timestamp): range_func = date_range else: range_func = timedelta_range breaks = range_func(start=start, end=end, periods=periods, freq=freq) return IntervalIndex.from_breaks(breaks, name=name, closed=closed)
def interval_range(start=None, end=None, periods=None, freq=None, name=None, closed='right'): """ Return a fixed frequency IntervalIndex Parameters ---------- start : numeric or datetime-like, default None Left bound for generating intervals end : numeric or datetime-like, default None Right bound for generating intervals periods : integer, default None Number of periods to generate freq : numeric, string, or DateOffset, default None The length of each interval. Must be consistent with the type of start and end, e.g. 2 for numeric, or '5H' for datetime-like. Default is 1 for numeric and 'D' (calendar daily) for datetime-like. name : string, default None Name of the resulting IntervalIndex closed : string, default 'right' options are: 'left', 'right', 'both', 'neither' Notes ----- Of the three parameters: ``start``, ``end``, and ``periods``, exactly two must be specified. Returns ------- rng : IntervalIndex Examples -------- Numeric ``start`` and ``end`` is supported. >>> pd.interval_range(start=0, end=5) IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]] closed='right', dtype='interval[int64]') Additionally, datetime-like input is also supported. >>> pd.interval_range(start=pd.Timestamp('2017-01-01'), end=pd.Timestamp('2017-01-04')) IntervalIndex([(2017-01-01, 2017-01-02], (2017-01-02, 2017-01-03], (2017-01-03, 2017-01-04]] closed='right', dtype='interval[datetime64[ns]]') The ``freq`` parameter specifies the frequency between the left and right. endpoints of the individual intervals within the ``IntervalIndex``. For numeric ``start`` and ``end``, the frequency must also be numeric. >>> pd.interval_range(start=0, periods=4, freq=1.5) IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]] closed='right', dtype='interval[float64]') Similarly, for datetime-like ``start`` and ``end``, the frequency must be convertible to a DateOffset. >>> pd.interval_range(start=pd.Timestamp('2017-01-01'), periods=3, freq='MS') IntervalIndex([(2017-01-01, 2017-02-01], (2017-02-01, 2017-03-01], (2017-03-01, 2017-04-01]] closed='right', dtype='interval[datetime64[ns]]') The ``closed`` parameter specifies which endpoints of the individual intervals within the ``IntervalIndex`` are closed. >>> pd.interval_range(end=5, periods=4, closed='both') IntervalIndex([[1, 2], [2, 3], [3, 4], [4, 5]] closed='both', dtype='interval[int64]') See Also -------- IntervalIndex : an Index of intervals that are all closed on the same side. """ if com._count_not_none(start, end, periods) != 2: raise ValueError('Of the three parameters: start, end, and periods, ' 'exactly two must be specified') start = com._maybe_box_datetimelike(start) end = com._maybe_box_datetimelike(end) endpoint = next(com._not_none(start, end)) if not _is_valid_endpoint(start): msg = 'start must be numeric or datetime-like, got {start}' raise ValueError(msg.format(start=start)) if not _is_valid_endpoint(end): msg = 'end must be numeric or datetime-like, got {end}' raise ValueError(msg.format(end=end)) if is_float(periods): periods = int(periods) elif not is_integer(periods) and periods is not None: msg = 'periods must be a number, got {periods}' raise TypeError(msg.format(periods=periods)) freq = freq or (1 if is_number(endpoint) else 'D') if not is_number(freq): try: freq = to_offset(freq) except ValueError: raise ValueError('freq must be numeric or convertible to ' 'DateOffset, got {freq}'.format(freq=freq)) # verify type compatibility if not all([_is_type_compatible(start, end), _is_type_compatible(start, freq), _is_type_compatible(end, freq)]): raise TypeError("start, end, freq need to be type compatible") if is_number(endpoint): if periods is None: periods = int((end - start) // freq) if start is None: start = end - periods * freq # force end to be consistent with freq (lower if freq skips over end) end = start + periods * freq # end + freq for inclusive endpoint breaks = np.arange(start, end + freq, freq) elif isinstance(endpoint, Timestamp): # add one to account for interval endpoints (n breaks = n-1 intervals) if periods is not None: periods += 1 breaks = date_range(start=start, end=end, periods=periods, freq=freq) else: # add one to account for interval endpoints (n breaks = n-1 intervals) if periods is not None: periods += 1 breaks = timedelta_range(start=start, end=end, periods=periods, freq=freq) return IntervalIndex.from_breaks(breaks, name=name, closed=closed)
def _generate(cls, start, end, periods, name, offset, tz=None, normalize=False): if com._count_not_none(start, end, periods) < 2: raise ValueError('Must specify two of start, end, or periods') _normalized = True if start is not None: start = Timestamp(start) if end is not None: end = Timestamp(end) inferred_tz = tools._infer_tzinfo(start, end) if tz is not None and inferred_tz is not None: assert (inferred_tz == tz) elif inferred_tz is not None: tz = inferred_tz tz = tools._maybe_get_tz(tz) if start is not None: if normalize: start = normalize_date(start) _normalized = True else: _normalized = _normalized and start.time() == _midnight if end is not None: if normalize: end = normalize_date(end) _normalized = True else: _normalized = _normalized and end.time() == _midnight if hasattr(offset, 'delta') and offset != offsets.Day(): if inferred_tz is None and tz is not None: # naive dates if start is not None and start.tz is None: start = start.tz_localize(tz) if end is not None and end.tz is None: end = end.tz_localize(tz) if start and end: if start.tz is None and end.tz is not None: start = start.tz_localize(end.tz) if end.tz is None and start.tz is not None: end = end.tz_localize(start.tz) if (offset._should_cache() and not (offset._normalize_cache and not _normalized) and _naive_in_cache_range(start, end)): index = cls._cached_range(start, end, periods=periods, offset=offset, name=name) else: index = _generate_regular_range(start, end, periods, offset) else: if inferred_tz is None and tz is not None: # naive dates if start is not None and start.tz is not None: start = start.replace(tzinfo=None) if end is not None and end.tz is not None: end = end.replace(tzinfo=None) if start and end: if start.tz is None and end.tz is not None: end = end.replace(tzinfo=None) if end.tz is None and start.tz is not None: start = start.replace(tzinfo=None) if (offset._should_cache() and not (offset._normalize_cache and not _normalized) and _naive_in_cache_range(start, end)): index = cls._cached_range(start, end, periods=periods, offset=offset, name=name) else: index = _generate_regular_range(start, end, periods, offset) if tz is not None and getattr(index, 'tz', None) is None: index = lib.tz_localize_to_utc(com._ensure_int64(index), tz) index = index.view(_NS_DTYPE) index = index.view(cls) index.name = name index.offset = offset index.tz = tz return index
def _generate(cls, start, end, periods, name, offset, tz=None, normalize=False): if com._count_not_none(start, end, periods) < 2: raise ValueError('Must specify two of start, end, or periods') _normalized = True if start is not None: start = Timestamp(start) if end is not None: end = Timestamp(end) inferred_tz = tools._infer_tzinfo(start, end) if tz is not None and inferred_tz is not None: assert(inferred_tz == tz) elif inferred_tz is not None: tz = inferred_tz tz = tools._maybe_get_tz(tz) if start is not None: if normalize: start = normalize_date(start) _normalized = True else: _normalized = _normalized and start.time() == _midnight if end is not None: if normalize: end = normalize_date(end) _normalized = True else: _normalized = _normalized and end.time() == _midnight if hasattr(offset, 'delta') and offset != offsets.Day(): if inferred_tz is None and tz is not None: # naive dates if start is not None and start.tz is None: start = start.tz_localize(tz) if end is not None and end.tz is None: end = end.tz_localize(tz) if start and end: if start.tz is None and end.tz is not None: start = start.tz_localize(end.tz) if end.tz is None and start.tz is not None: end = end.tz_localize(start.tz) if (offset._should_cache() and not (offset._normalize_cache and not _normalized) and _naive_in_cache_range(start, end)): index = cls._cached_range(start, end, periods=periods, offset=offset, name=name) else: index = _generate_regular_range(start, end, periods, offset) else: if inferred_tz is None and tz is not None: # naive dates if start is not None and start.tz is not None: start = start.replace(tzinfo=None) if end is not None and end.tz is not None: end = end.replace(tzinfo=None) if start and end: if start.tz is None and end.tz is not None: end = end.replace(tzinfo=None) if end.tz is None and start.tz is not None: start = start.replace(tzinfo=None) if (offset._should_cache() and not (offset._normalize_cache and not _normalized) and _naive_in_cache_range(start, end)): index = cls._cached_range(start, end, periods=periods, offset=offset, name=name) else: index = _generate_regular_range(start, end, periods, offset) if tz is not None and getattr(index, 'tz', None) is None: index = lib.tz_localize_to_utc(com._ensure_int64(index), tz) index = index.view(_NS_DTYPE) index = index.view(cls) index.name = name index.offset = offset index.tz = tz return index
def _needs_reindex_multi(self, axes, method, level): # only allowing multi-index on Panel (and not > dims) return method is None and not self._is_mixed_type and self._AXIS_LEN <= 3 and com._count_not_none( *axes.values()) == 3
def plot(self, bar='candle', start_view=None, end_view=None, periods_view=None, shift=None, start_plot=None, end_plot=None, periods_plot=None, showgrid=True, validate=False, **kwargs): """Retrun plotly candle chart graph Usage: `fx.plot()` * Args: * bar: 'candle', 'c' -> candle_plot / 'heikin', 'h' -> heikin_ashi plot * start, end: 最初と最後のdatetime, 'first'でindexの最初、'last'でindexの最後 * periods: 足の本数 > **start, end, periods合わせて2つの引数が必要** * shift: shiftの本数の足だけ右側に空白 * Return: グラフデータとレイアウト(plotly.graph_objs.graph_objs.Figure) """ # ---------Set "plot_dataframe"---------- # Default Args if com._count_not_none(start_plot, end_plot, periods_plot) == 0: end_plot = 'last' periods_plot = 300 try: # first/last start_plot = self.stock_dataframe.index[0] if start_plot == 'first' else start_plot end_plot = self.stock_dataframe.index[-1] if end_plot == 'last' else end_plot except AttributeError: raise AttributeError('{} Use `fx.resample(<TimeFrame>)` at first' .format(type(self.stock_dataframe))) # Set "plot_dataframe" start_plot, end_plot = set_span(start_plot, end_plot, periods_plot, self.freq) if bar in ('candle', 'c'): plot_dataframe = self.stock_dataframe.loc[start_plot:end_plot] self._fig = FF.create_candlestick(plot_dataframe.open, plot_dataframe.high, plot_dataframe.low, plot_dataframe.close, dates=plot_dataframe.index) elif bar in ('heikin', 'h'): self.stock_dataframe.heikin_ashi() plot_dataframe = self.stock_dataframe.loc[start_plot:end_plot] self._fig = FF.create_candlestick(plot_dataframe.hopen, plot_dataframe.hhigh, plot_dataframe.hlow, plot_dataframe.hclose, dates=plot_dataframe.index) else: raise KeyError('Use bar = "[c]andle" or "[h]eikin"') # ---------Append indicators---------- for indicator in self._indicators.keys(): self._append_graph(indicator, start_plot, end_plot) # Re-append indicator in graph # ---------Set "view"---------- # Default Args if com._count_not_none(start_view, end_view, periods_view) == 0: end_view = 'last' periods_view = 50 # first/last start_view = plot_dataframe.index[0] if start_view == 'first' else start_view end_view = plot_dataframe.index[-1] if end_view == 'last' else end_view # Set "view" start_view, end_view = set_span(start_view, end_view, periods_view, self.freq) end_view = set_span(start=end_view, periods=shift, freq=self.freq)[-1] if shift else end_view view = list(to_unix_time(start_view, end_view)) # ---------Plot graph---------- self._fig['layout'].update(xaxis={'showgrid': showgrid, 'range': view}, yaxis={"autorange": True}) return self._fig
def _generate(cls, start, end, periods, name, offset, tz=None, normalize=False): _normalized = True if start is not None: start = Timestamp(start) if end is not None: end = Timestamp(end) inferred_tz = tools._infer_tzinfo(start, end) if tz is not None and inferred_tz is not None: assert inferred_tz == tz elif inferred_tz is not None: tz = inferred_tz if inferred_tz is None and tz is not None: # naive dates if start is not None and start.tz is None: start = start.tz_localize(tz) if end is not None and end.tz is None: end = end.tz_localize(tz) elif inferred_tz is not None: pass if start and end: if start.tz is None and end.tz is not None: start = start.tz_localize(end.tz) if end.tz is None and start.tz is not None: end = end.tz_localize(start.tz) if start is not None: if normalize: start = normalize_date(start) _normalized = True else: _normalized = _normalized and start.time() == _midnight if end is not None: if normalize: end = normalize_date(end) _normalized = True else: _normalized = _normalized and end.time() == _midnight tz = tools._maybe_get_tz(tz) if com._count_not_none(start, end, periods) < 2: raise ValueError("Must specify two of start, end, or periods") if ( offset._should_cache() and not (offset._normalize_cache and not _normalized) and _naive_in_cache_range(start, end) ): index = cls._cached_range(start, end, periods=periods, offset=offset, name=name) else: index = _generate_regular_range(start, end, periods, offset) index = index.view(cls) index.name = name index.offset = offset index.tz = tz return index