class CADataFrame::LocAccessor

Public Class Methods

new(dataframe) click to toggle source
# File lib/carray-dataframe/loc_accessor.rb, line 5
def initialize (dataframe)
  @dataframe = dataframe
end

Public Instance Methods

[](*argv) click to toggle source
# File lib/carray-dataframe/loc_accessor.rb, line 9
def [] (*argv)
  @dataframe.instance_eval {
    index = argv.first
    case index
    when nil
    when CArray
    when Integer      ### df[3]
      index = [index]
    when Range        ### df["a".."d"]
      if @row_index
        idx1 = @row_index.search(index.begin)
        idx2 = @row_index.search(index.end)
        if idx1 and idx2
          index = idx1..idx2
        elsif index.begin.is_a?(Integer) || index.end.is_a?(Integer)
          iloc[*argv]
        else
          raise "invalid index '#{index}'"
        end
      end
    when Array
      if index[0].is_a?(Range)
        if @row_index
          range = index[0]
          idx1 = @row_index.search(range.begin)
          idx2 = @row_index.search(range.end)
          if idx1 and idx2
            range = idx1..idx2
          elsif range.begin.is_a?(Integer) || range.end.is_a?(Integer)
          else
            raise "invalid index '#{index}'"
          end
          index[0] = range
        end            
      end
    else
      if @row_index
        idx1 = @row_index.search(index)
        if idx1
          index = [idx1]
        else
          raise "invalid index '#{index}'"
        end
      end
    end
    column_selector = select_columns(argv[1])
    columns = {}
    column_selector.each do |name|
      columns[name] = @column_data[name][index] ### df[...]
    end
    return CADataFrame.new(columns, index: @row_index ? @row_index[index] : nil)
  }
end
[]=(*argv) click to toggle source
# File lib/carray-dataframe/loc_accessor.rb, line 63
def []= (*argv)
  value = argv.pop
  @dataframe.instance_eval {
    index = argv.first
    case index
    when nil
    when CArray          
    when Range         ### df["a".."d"] = value
      if @row_index
        idx1 = @row_index.search(index.begin)
        idx2 = @row_index.search(index.end)
        if idx1 and idx2
          index = idx1..idx2
        elsif index.begin.is_a?(Integer) || index.end.is_a?(Integer)
          iloc[*argv] = value
          return
        else
          raise "invalid index '#{index}'"
        end
      end
    when Array
      if index[0].is_a?(Range)
        if @row_index
          range = index[0]
          idx1 = @row_index.search(range.begin)
          idx2 = @row_index.search(range.end)
          if idx1 and idx2
            range = idx1..idx2
          elsif range.begin.is_a?(Integer) || range.end.is_a?(Integer)
          else
            raise "invalid index '#{index}'"
          end
          index[0] = range
        end            
      end
    else
      if @row_index
        idx1 = @row_index.search(index)
        if idx1
          index = [idx1]
        else
          raise "invalid index '#{index}'"
        end
      end
    end
    column_selector = select_columns(argv[1])
    case value
    when Hash          ### value = {"a"=> [1,2,3], ... }
      value = value.map{|k,v| [k.to_s, v]}.to_h
      column_selector.each do |name|
        @column_data[name][index] = value[name]
      end
    when Array
      case value.first
      when Hash        ### value = [{"a"=>1,"b"=>11}, {"a"=>2,""=>12} ...]
        table = {}
        column_selector.each do |name|
          table[name] = []
        end
        value.each do |hash|
          hash = hash.map{|k,v| [k.to_s, v]}.to_h
          column_selector.each do |name|
            table[name] << hash[name]
          end
        end
        column_selector.each do |name|
          @column_data[name][index] = table[name]
        end
      else             ### value = [[1,11],[2,12],...]
        value = value.transpose
        column_selector.each_with_index do |name, k|
          @column_data[name][index] = value[k]
        end
      end
    else               ### value = any value
      column_selector.each_with_index do |name, k|
        @column_data[name][index] = value
      end
    end
  }
end