from larray import *

# load 'demography_eurostat' dataset
demography_eurostat = load_example_data('demography_eurostat')

# extract the 'population' array from the dataset 
population = demography_eurostat.population
population

"""
Explanation: Import the LArray library:
End of explanation
"""


# Array summary: metadata + dimensions + description of axes
population.info

"""
Explanation: Inspecting Array objects
Get array summary : metadata + dimensions + description of axes + dtype + size in memory
End of explanation
"""


population.axes

"""
Explanation: Get axes
End of explanation
"""


population.axes.names

"""
Explanation: Get axis names
End of explanation
"""


population.ndim

"""
Explanation: Get number of dimensions
End of explanation
"""


population.shape

"""
Explanation: Get length of each dimension
End of explanation
"""


population.size

"""
Explanation: Get total number of elements of the array
End of explanation
"""


population.dtype

"""
Explanation: Get type of internal data (int, float, ...)
End of explanation
"""


population.memory_used

"""
Explanation: Get size in memory
End of explanation
"""


population.with_total('gender', label='Total')

"""
Explanation: Some Useful Functions
with total
Add totals to one or several axes:
End of explanation
"""


# where(condition, value if true, value if false)
where(population < population.mean('time'), -population, population)

"""
Explanation: See with_total for more details and examples.
where
The where function can be used to apply some computation depending on a condition:
End of explanation
"""


# values below 10 millions are set to 10 millions
population.clip(minval=10**7)

# values above 40 millions are set to 40 millions
population.clip(maxval=4*10**7)

# values below 10 millions are set to 10 millions and 
# values above 40 millions are set to 40 millions
population.clip(10**7, 4*10**7)

# Using vectors to define the lower and upper bounds
lower_bound = sequence(population.time, initial=5_500_000, inc=50_000)
upper_bound = sequence(population.time, 41_000_000, inc=100_000)

print(lower_bound, '\n')
print(upper_bound, '\n')

population.clip(lower_bound, upper_bound)

"""
Explanation: See where for more details and examples.
clip
Set all data between a certain range:
End of explanation
"""


divisor = ones(population.axes, dtype=int)
divisor['Male'] = 0
divisor

population / divisor

# we use astype(int) since the divnot0 method 
# returns a float array in this case while 
# we want an integer array
population.divnot0(divisor).astype(int)

"""
Explanation: See clip for more details and examples.
divnot0
Replace division by 0 by 0:
End of explanation
"""


population.ratio('gender')

# which is equivalent to
population / population.sum('gender')

"""
Explanation: See divnot0 for more details and examples.
ratio
The ratio (rationot0) method returns an array with all values divided by the sum of values along given axes:
End of explanation
"""


# or, if you want the previous ratios in percents
population.percent('gender')

"""
Explanation: See ratio and rationot0 for more details and examples.
percents
End of explanation
"""


# calculates 'diff[year+1] = population[year+1] - population[year]'
population.diff('time')

# calculates 'diff[year+2] = population[year+2] - population[year]'
population.diff('time', d=2)

# calculates 'diff[year] = population[year+1] - population[year]'
population.diff('time', label='lower')

"""
Explanation: See percent for more details and examples.
diff
The diff method calculates the n-th order discrete difference along a given axis.
The first order difference is given by out[n+1] = in[n+1] - in[n] along the given axis.
End of explanation
"""


population.growth_rate('time')

"""
Explanation: See diff for more details and examples.
growth_rate
The growth_rate method calculates the growth along a given axis.
It is roughly equivalent to a.diff(axis, d, label) / a[axis.i[:-d]]:
End of explanation
"""


population.shift('time')

# when shift is applied on an (increasing) time axis,
# it effectively brings "past" data into the future
population_shifted = population.shift('time')
stack({'population_shifted_2014': population_shifted[2014], 'population_2013': population[2013]}, 'array')

"""
Explanation: See growth_rate for more details and examples.
shift
The shift method drops first label of an axis and shifts all subsequent labels
End of explanation
"""


