Current section
Files
Jump to
Current section
Files
lib/data_frame.ex
defmodule DataFrame do
@moduledoc """
Functions to create and modify a Frame, a structure with a 2D table with information, indexes and columns
"""
alias DataFrame.Table
alias DataFrame.Frame
def new(table, index, columns) do
%Frame{values: table, index: index, columns: columns}
end
def new(table_with_index, columns) do
index = Table.columns(table_with_index, 0..0)
table = Table.columns(table_with_index, 1..-1)
%Frame{values: table, index: index, columns: columns}
end
def head(frame, size \\ 5) do
DataFrame.new(Enum.take(frame.values, size), Enum.take(frame.index, size), frame.columns)
end
def tail(frame, the_size \\ 5) do
size = -the_size
head(frame, size)
end
def transpose(frame) do
%Frame{values: Table.transpose(frame.values), index: frame.columns, columns: frame.index}
end
def sort_index(frame, ascending \\ true) do
sort(frame, 0, ascending)
end
def sort_values(frame, column_name, ascending \\ true) do
index = Enum.find_index(frame.columns, fn(x) -> x == column_name end)
sort(frame, index + 1, ascending)
end
defp sort(frame, column_index, ascending) do
sorting_func = if ascending do
fn(x,y) -> Enum.at(x, column_index) > Enum.at(y, column_index) end
else
fn(x,y) -> Enum.at(x, column_index) < Enum.at(y, column_index) end
end
frame.values
|> Table.add_column(frame.index)
|> Enum.sort(fn(x,y) -> sorting_func.(x,y) end)
|> DataFrame.new(frame.columns)
end
def loc(frame, index_range, column_range) do
# Assume the range is continuous in the data also.
index = Enum.find_index(frame.index, fn(x) -> to_string(x) == to_string(Enum.at(index_range, 0)) end)
column = Enum.find_index(frame.columns, fn(x) -> to_string(x) == to_string(Enum.at(column_range, 0)) end)
index_range_integer = index..(index + Enum.count(index_range) - 1)
column_range_integer = column..(column + Enum.count(column_range) - 1)
DataFrame.iloc(frame, index_range_integer, column_range_integer)
end
def iloc(frame, index, columns) do
new_index = frame.index |> Enum.slice(index)
new_columns = frame.columns |> Enum.slice(columns)
values = frame.values |> Table.slice(index, columns)
DataFrame.new(values, new_index, new_columns)
end
def at(frame, index_name, column_name) do
index = Enum.find_index(frame.index, fn(x) -> to_string(x) == to_string(index_name) end)
column = Enum.find_index(frame.columns, fn(x) -> to_string(x) == to_string(column_name) end)
DataFrame.iat(frame, index, column)
end
def iat(frame, index, column) do
Table.at(frame.values, index, column)
end
end
#DataFrame.new(Table.build_random(6,4), DateRange.new("2016-09-12", 6), [1,3,4,5])