def linspace(start: Union[float, np.float64, int, np.int64], stop: Union[float, np.float64, int, np.int64], length: Union[int, np.int64]) -> pdarray: """ Create a pdarray of linearly-spaced floats in a closed interval. Parameters ---------- start : Union[float,np.float64, int, np.int64] Start of interval (inclusive) stop : Union[float,np.float64, int, np.int64] End of interval (inclusive) length : Union[int,np.int64] Number of points Returns ------- pdarray, float64 Array of evenly spaced float values along the interval Raises ------ TypeError Raised if start or stop is not a float or int or if length is not an int See Also -------- arange Notes ----- If that start is greater than stop, the pdarray values are generated in descending order. Examples -------- >>> ak.linspace(0, 1, 5) array([0, 0.25, 0.5, 0.75, 1]) >>> ak.linspace(start=1, stop=0, length=5) array([1, 0.75, 0.5, 0.25, 0]) >>> ak.linspace(start=-5, stop=0, length=5) array([-5, -3.75, -2.5, -1.25, 0]) """ if not isSupportedNumber(start) or not isSupportedNumber(stop): raise TypeError( 'both start and stop must be an int, np.int64, float, or np.float64' ) if not isSupportedNumber(length): raise TypeError('length must be an int or int64') repMsg = generic_msg(cmd='linspace', args="{} {} {}".format(start, stop, length)) return create_pdarray(repMsg)
def where(condition: pdarray, A: Union[numeric_scalars, pdarray], B: Union[numeric_scalars, pdarray]) -> pdarray: """ Returns an array with elements chosen from A and B based upon a conditioning array. As is the case with numpy.where, the return array consists of values from the first array (A) where the conditioning array elements are True and from the second array (B) where the conditioning array elements are False. Parameters ---------- condition : pdarray Used to choose values from A or B A : Union[numeric_scalars, pdarray] Value(s) used when condition is True B : Union[numeric_scalars, pdarray] Value(s) used when condition is False Returns ------- pdarray Values chosen from A where the condition is True and B where the condition is False Raises ------ TypeError Raised if the condition object is not a pdarray, if A or B is not an int, np.int64, float, np.float64, or pdarray, if pdarray dtypes are not supported or do not match, or multiple condition clauses (see Notes section) are applied ValueError Raised if the shapes of the condition, A, and B pdarrays are unequal Examples -------- >>> a1 = ak.arange(1,10) >>> a2 = ak.ones(9, dtype=np.int64) >>> cond = a1 < 5 >>> ak.where(cond,a1,a2) array([1, 2, 3, 4, 1, 1, 1, 1, 1]) >>> a1 = ak.arange(1,10) >>> a2 = ak.ones(9, dtype=np.int64) >>> cond = a1 == 5 >>> ak.where(cond,a1,a2) array([1, 1, 1, 1, 5, 1, 1, 1, 1]) >>> a1 = ak.arange(1,10) >>> a2 = 10 >>> cond = a1 < 5 >>> ak.where(cond,a1,a2) array([1, 2, 3, 4, 10, 10, 10, 10, 10]) Notes ----- A and B must have the same dtype and only one conditional clause is supported e.g., n < 5, n > 1, which is supported in numpy is not currently supported in Arkouda """ if (not isSupportedNumber(A) and not isinstance(A,pdarray)) or \ (not isSupportedNumber(B) and not isinstance(B,pdarray)): raise TypeError( 'both A and B must be an int, np.int64, float, np.float64, or pdarray' ) if isinstance(A, pdarray) and isinstance(B, pdarray): repMsg = generic_msg(cmd="efunc3vv", args="{} {} {} {}".\ format("where", condition.name, A.name, B.name)) # For scalars, try to convert it to the array's dtype elif isinstance(A, pdarray) and np.isscalar(B): repMsg = generic_msg(cmd="efunc3vs", args="{} {} {} {} {}".\ format("where", condition.name, A.name, A.dtype.name, A.format_other(B))) elif isinstance(B, pdarray) and np.isscalar(A): repMsg = generic_msg(cmd="efunc3sv", args="{} {} {} {} {}".\ format("where", condition.name, B.dtype.name, B.format_other(A), B.name)) elif np.isscalar(A) and np.isscalar(B): # Scalars must share a common dtype (or be cast) dtA = resolve_scalar_dtype(A) dtB = resolve_scalar_dtype(B) # Make sure at least one of the dtypes is supported if not (dtA in DTypes or dtB in DTypes): raise TypeError( ("Not implemented for scalar types {} " + "and {}").format( dtA, dtB)) # If the dtypes are the same, do not cast if dtA == dtB: # type: ignore dt = dtA # If the dtypes are different, try casting one direction then the other elif dtB in DTypes and np.can_cast(A, dtB): A = np.dtype(dtB).type(A) dt = dtB elif dtA in DTypes and np.can_cast(B, dtA): B = np.dtype(dtA).type(B) dt = dtA # Cannot safely cast else: raise TypeError(("Cannot cast between scalars {} and {} to " + "supported dtype").format(A, B)) repMsg = generic_msg(cmd="efunc3ss", args="{} {} {} {} {} {}".\ format("where", condition.name, dt, A, dt, B)) return create_pdarray(type_cast(str, repMsg))
def random_strings_lognormal(logmean : numeric_scalars, logstd : numeric_scalars, size : int_scalars, characters : str='uppercase', seed : Optional[int_scalars]=None) -> Strings: """ Generate random strings with log-normally distributed lengths and with characters drawn from a specified set. Parameters ---------- logmean : numeric_scalars The log-mean of the length distribution logstd : numeric_scalars The log-standard-deviation of the length distribution size : int_scalars The number of strings to generate characters : (uppercase, lowercase, numeric, printable, binary) The set of characters to draw from seed : int_scalars, optional Value used to initialize the random number generator Returns ------- Strings The Strings object encapsulating a pdarray of random strings Raises ------ TypeError Raised if logmean is neither a float nor a int, logstd is not a float, size is not an int, or if characters is not a str ValueError Raised if logstd <= 0 or size < 0 See Also -------- random_strings_lognormal, randint Notes ----- The lengths of the generated strings are distributed $Lognormal(\\mu, \\sigma^2)$, with :math:`\\mu = logmean` and :math:`\\sigma = logstd`. Thus, the strings will have an average length of :math:`exp(\\mu + 0.5*\\sigma^2)`, a minimum length of zero, and a heavy tail towards longer strings. Examples -------- >>> ak.random_strings_lognormal(2, 0.25, 5, seed=1) array(['TVKJTE', 'ABOCORHFM', 'LUDMMGTB', 'KWOQNPHZ', 'VSXRRL']) >>> ak.random_strings_lognormal(2, 0.25, 5, seed=1, characters='printable') array(['+5"fp-', ']3Q4kC~HF', '=F=`,IE!', 'DjkBa'9(', '5oZ1)=']) """ if not isSupportedNumber(logmean) or not isSupportedNumber(logstd): raise TypeError('both logmean and logstd must be an int, np.int64, float, or np.float64') if logstd <= 0 or size < 0: raise ValueError("Incompatible arguments: logstd <= 0 or size < 0") repMsg = generic_msg(cmd="randomStrings", args="{} {} {} {} {} {}".\ format(NUMBER_FORMAT_STRINGS['int64'].format(size), "lognormal", characters, NUMBER_FORMAT_STRINGS['float64'].format(logmean), NUMBER_FORMAT_STRINGS['float64'].format(logstd), seed)) return Strings(*(cast(str,repMsg).split('+')))