go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/tables/column.go (about)

     1  package tables
     2  
     3  import (
     4  	"go-ml.dev/pkg/base/fu"
     5  	"go-ml.dev/pkg/zorros"
     6  	"reflect"
     7  )
     8  
     9  type Column struct {
    10  	column reflect.Value
    11  	na     fu.Bits
    12  }
    13  
    14  /*
    15  Col returns Column wrapper over slice
    16  */
    17  func Col(a interface{}) *Column {
    18  	v := reflect.ValueOf(a)
    19  	if v.Kind() != reflect.Slice {
    20  		panic("anly slice is allowed as an argument")
    21  	}
    22  	return &Column{v, fu.Bits{}}
    23  }
    24  
    25  func (c *Column) Table(n string) *Table {
    26  	return MakeTable([]string{n}, []reflect.Value{c.column}, []fu.Bits{c.na}, c.Len())
    27  }
    28  
    29  /*
    30  Text returns column' value converted to string
    31  
    32  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
    33  	t.Col("Name").Text(0) -> "Ivanov"
    34  	t.Col("Name").Index(0).String() -> "Ivanov"
    35  */
    36  func (c *Column) Text(row int) string {
    37  	return c.Index(row).String()
    38  }
    39  
    40  func (c *Column) Na(i int) bool {
    41  	return c.na.Bit(i)
    42  }
    43  
    44  /*
    45  Strings extracts column' values as []string
    46  
    47  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
    48  	t.Col("Name").Strings() -> {"Ivanov","Petrow"}
    49  */
    50  func (c *Column) Strings() []string {
    51  	return c.ExtractAs(fu.String).([]string)
    52  }
    53  
    54  /*
    55  TzeInt returns column' value converted to int
    56  
    57  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
    58  	t.Col("Age").TzeInt(0) -> 32
    59  	t.Col("Age").Index(0).TzeInt() -> 32
    60  */
    61  func (c *Column) Int(row int) int {
    62  	return c.Index(row).Int()
    63  }
    64  
    65  /*
    66  Int8 returns column' value converted to int8
    67  
    68  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
    69  	t.Col("Age").Int8(0) -> 32
    70  	t.Col("Age").Index().Int8() -> 32
    71  */
    72  func (c *Column) Int8(row int) int8 {
    73  	return c.Index(row).Int8()
    74  }
    75  
    76  /*
    77  Int16 returns column' value converted to int16
    78  
    79  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
    80  	t.Col("Age").Int16(0) -> 32
    81  	t.Col("Age").Index().Int16() -> 32
    82  */
    83  func (c *Column) Int16(row int) int16 {
    84  	return c.Index(row).Int16()
    85  }
    86  
    87  /*
    88  Int32 returns column' value converted to int32
    89  
    90  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
    91  	t.Col("Age").Int32(0) -> 32
    92  	t.Col("Age").Index(0).Int32() -> 32
    93  */
    94  func (c *Column) Int32(row int) int32 {
    95  	return c.Index(row).Int32()
    96  }
    97  
    98  /*
    99  Int64 returns column' value converted to int64
   100  
   101  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   102  	t.Col("Age").Int64(0) -> 32
   103  	t.Col("Age").Index(0).Int64() -> 32
   104  */
   105  func (c *Column) Int64(row int) int64 {
   106  	return c.Index(row).Int64()
   107  }
   108  
   109  /*
   110  Uint returns column' value converted to uint
   111  
   112  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   113  	t.Col("Age").Uint(0) -> 32
   114  */
   115  func (c *Column) Uint(row int) uint {
   116  	return c.Index(row).Uint()
   117  }
   118  
   119  /*
   120  Uint8 returns column' value converted to uint8
   121  
   122  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   123  	t.Col("Age").Uint8(0) -> 32
   124  */
   125  func (c *Column) Uint8(row int) uint8 {
   126  	return c.Index(row).Uint8()
   127  }
   128  
   129  /*
   130  Uint16 returns column' value converted to uint16
   131  
   132  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   133  	t.Col("Age").Uint16(0) -> 32
   134  */
   135  func (c *Column) Uint16(row int) uint16 {
   136  	return c.Index(row).Uint16()
   137  }
   138  
   139  /*
   140  Uint32 returns column' value converted to uint32
   141  
   142  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   143  	t.Col("Age").Uint32(0) -> 32
   144  */
   145  func (c *Column) Uint32(row int) uint32 {
   146  	return c.Index(row).Uint32()
   147  }
   148  
   149  /*
   150  Uint64 returns column' value converted to uint64
   151  
   152  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   153  	t.Col("Age").Uint64(0) -> 32
   154  	t.Col("Age").Index(0).Uint64() -> 32
   155  */
   156  func (c *Column) Uint64(row int) uint64 {
   157  	return c.Index(row).Uint64()
   158  }
   159  
   160  /*
   161  Ints extracts column' values as []int
   162  
   163  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   164  	t.Col("Age").Ints() -> {32,44}
   165  */
   166  func (c *Column) Ints() []int {
   167  	return c.ExtractAs(fu.Int).([]int)
   168  }
   169  
   170  /*
   171  Ints8 extracts column' values as []int8
   172  
   173  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   174  	t.Col("Age").Ints8() -> {32,44}
   175  */
   176  func (c *Column) Ints8() []int8 {
   177  	return c.ExtractAs(fu.Int8).([]int8)
   178  }
   179  
   180  /*
   181  Ints16 extracts column' values as []int16
   182  
   183  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   184  	t.Col("Age").Ints16() -> {32,44}
   185  */
   186  func (c *Column) Ints16() []int16 {
   187  	return c.ExtractAs(fu.Int16).([]int16)
   188  }
   189  
   190  /*
   191  Ints32 extracts column' values as []int32
   192  
   193  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   194  	t.Col("Age").Ints32() -> {32,44}
   195  */
   196  func (c *Column) Ints32() []int32 {
   197  	return c.ExtractAs(fu.Int32).([]int32)
   198  }
   199  
   200  /*
   201  Ints64 extracts column' values as []int64
   202  
   203  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   204  	t.Col("Age").Ints64() -> {32,44}
   205  */
   206  func (c *Column) Ints64() []int64 {
   207  	return c.ExtractAs(fu.Int64).([]int64)
   208  }
   209  
   210  /*
   211  Uints extracts column' values as []uint
   212  
   213  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   214  	t.Col("Age").Uints() -> {32,44}
   215  */
   216  func (c *Column) Uints() []uint {
   217  	return c.ExtractAs(fu.Uint).([]uint)
   218  }
   219  
   220  /*
   221  Uints8 extracts column' values as []uint8
   222  
   223  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   224  	t.Col("Age").Uints8() -> {32,44}
   225  */
   226  func (c *Column) Uints8() []uint8 {
   227  	return c.ExtractAs(fu.Uint8).([]uint8)
   228  }
   229  
   230  /*
   231  Uints16 extracts column' values as []uint16
   232  
   233  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   234  	t.Col("Age").Uints16() -> {32,44}
   235  */
   236  func (c *Column) Uints16() []uint16 {
   237  	return c.ExtractAs(fu.Uint16).([]uint16)
   238  }
   239  
   240  /*
   241  Uints32 extracts column' values as []uint32
   242  
   243  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   244  	t.Col("Age").Uints32() -> {32,44}
   245  */
   246  func (c *Column) Uints32() []uint32 {
   247  	return c.ExtractAs(fu.Uint32).([]uint32)
   248  }
   249  
   250  /*
   251  Uints64 extracts column' values as []uint64
   252  
   253  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   254  	t.Col("Age").Uints64() -> {32,44}
   255  */
   256  func (c *Column) Uints64() []uint64 {
   257  	return c.ExtractAs(fu.Uint64).([]uint64)
   258  }
   259  
   260  /*
   261  Float32 returns column' value converted to float32
   262  
   263  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   264  	t.Col("Rate").Float32(0) -> 1.2
   265  */
   266  func (c *Column) Real(row int) float32 {
   267  	return c.Index(row).Real()
   268  }
   269  
   270  /*
   271  Float returns column' value converted to float64
   272  
   273  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   274  	t.Col("Rate").Float(0) -> 1.2
   275  */
   276  func (c *Column) Float(row int) float64 {
   277  	return c.Index(row).Float()
   278  }
   279  
   280  /*
   281  Reals extracts column' values as []float32
   282  
   283  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   284  	t.Col("Rate").Reals() -> {1.2,1.5}
   285  */
   286  func (c *Column) Reals() []float32 {
   287  	return c.ExtractAs(fu.Float32).([]float32)
   288  }
   289  
   290  /*
   291  Floats extracts column' values as []float64
   292  
   293  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   294  	t.Col("Rate").Floats() -> {1.2,1.5}
   295  */
   296  func (c *Column) Floats() []float64 {
   297  	return c.ExtractAs(fu.Float64).([]float64)
   298  }
   299  
   300  /*
   301  Bool returns column' value converted to bool
   302  */
   303  func (c *Column) Bool(row int) bool {
   304  	return c.Index(row).Bool()
   305  }
   306  
   307  /*
   308  Bools extracts column' values as []bool
   309  */
   310  func (c *Column) Bools() []bool {
   311  	return c.ExtractAs(fu.Bool).([]bool)
   312  }
   313  
   314  /*
   315  Interface returns column' value as is
   316  
   317  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   318  	t.Col("Rate").Interface(0).(float32) -> 1.2
   319  	t.Col("Rate").Index(0).Interface().(float32) -> 1.2
   320  */
   321  func (c *Column) Interface(row int) interface{} {
   322  	return c.Index(row).Interface()
   323  }
   324  
   325  /*
   326  Tensor returns column' values as Tensor if it's a Tensor
   327  */
   328  func (c *Column) Tensor(row int) fu.Tensor {
   329  	return c.Index(row).Interface().(fu.Tensor)
   330  }
   331  
   332  /*
   333  ExtractAs extracts values as array with specified type
   334  
   335  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   336  	t.Col("Age").ExtractAs(reflect.TypeOf("")).([]string)[0] -> "32"
   337  	t.Col("Rate").ExtractAs(reflect.TypeOf(int(0))).([]int)[0] -> 1
   338  */
   339  func (c *Column) ExtractAs(tp reflect.Type, nocopy ...bool) interface{} {
   340  	if c.column.Type().Elem() == tp {
   341  		l := c.column.Len()
   342  		if fu.Fnzb(nocopy...) {
   343  			return c.column.Interface()
   344  		}
   345  		r := reflect.MakeSlice(c.column.Type(), l, l)
   346  		reflect.Copy(r, c.column)
   347  		return r.Interface()
   348  	} else {
   349  		return fu.ConvertSlice(c.column, c.na, tp, nocopy...).Interface()
   350  	}
   351  }
   352  
   353  /*
   354  Inspect returns raw array of column's values
   355  
   356  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   357  	t.Col("Name").Inspect().([]string)[0] -> "Ivanov"
   358  	t.Col("Age").Inspect().([]int)[0] -> 32
   359  	t.Col("Rate").Inspect().([]float32)[0] -> 1.2
   360  */
   361  func (c *Column) Inspect() interface{} {
   362  	return c.column.Interface()
   363  }
   364  
   365  /*
   366  Type returns (reflect) type of column' values
   367  */
   368  func (c *Column) Type() reflect.Type {
   369  	return c.column.Type().Elem()
   370  }
   371  
   372  /*
   373  Len returns length of column
   374  
   375  	t := tables.New([]struct{Name string}{{"Ivanov"}})
   376  	c1 := t.Col("Name")
   377  	t.Append([]struct{Name string}{{"Petrov"}})
   378  	c2 := t.Col("Name")
   379  	c1.Len() -> 1
   380  	c2.Len() -> 2
   381  */
   382  func (c *Column) Len() int {
   383  	return c.column.Len()
   384  }
   385  
   386  /*
   387  Unique returns column with only unique values
   388  
   389  	t := tables.New([]struct{Name string}{{"Ivanov"}})
   390  	u1 := t.Col("Name").Unique()
   391  	t = t.Append([]struct{Name string}{{"Petrov"},{"Petrov"}})
   392  	u2 := t.Col("Name").Unique()
   393  	u1.Unique().Inspect() -> {}
   394  	u2.Unique().Len() -> 2
   395  */
   396  func (c *Column) Unique() *Column {
   397  	v := reflect.ValueOf(true)
   398  	m := reflect.MakeMap(reflect.MapOf(c.column.Type().Elem(), v.Type()))
   399  	r := reflect.MakeSlice(c.column.Type(), 0, 0)
   400  	for i := 0; i < c.column.Len(); i++ {
   401  		x := c.column.Index(i)
   402  		q := m.MapIndex(x)
   403  		if !q.IsValid() {
   404  			r = reflect.Append(r, x)
   405  			m.SetMapIndex(x, v)
   406  		}
   407  	}
   408  	return &Column{r, fu.Bits{}}
   409  }
   410  
   411  /*
   412  Index returns cell with value at specified index
   413  
   414  	t := tables.New([]struct{Age int}{{"33"}})
   415  	c := t.Col("Age").Index(0)
   416  	c.String() -> "33"
   417  	c.Float32() -> 33.0
   418  	c.TzeInt() -> 33
   419  */
   420  func (c *Column) Index(i int) fu.Cell {
   421  	return fu.Cell{c.column.Index(i)}
   422  }
   423  
   424  func (c *Column) Value(i int) reflect.Value {
   425  	return c.column.Index(i)
   426  }
   427  
   428  /*
   429  Max returns cell with max column' maximal value
   430  
   431  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   432  	t.Col("Age").Max().TzeInt() -> 44
   433  	t.Col("Rate").Max().Float32() -> 1.5
   434  */
   435  func (c *Column) Max() fu.Cell {
   436  	return fu.Cell{fu.MaxValue(c.column)}
   437  }
   438  
   439  /*
   440  Min returns cell with column' minimal value
   441  
   442  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   443  	t.Col("Age").Min().TzeInt() -> 32
   444  	t.Col("Rate").Min().Float32() -> 1.2
   445  */
   446  func (c *Column) Min() fu.Cell {
   447  	return fu.Cell{fu.MinValue(c.column)}
   448  }
   449  
   450  /*
   451  MaxIndex returns index of first column' maximal value
   452  
   453  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   454  	t.Col("Age").MaxIndex() -> 1
   455  */
   456  func (c *Column) MaxIndex() int {
   457  	return fu.MaxIndex(c.column)
   458  }
   459  
   460  /*
   461  MinIndex returns index of first column' minimal value
   462  
   463  	t := table.New([]struct{Name string; Age int; Rate float}{{"Ivanov",32,1.2},{"Petrov",44,1.5}})
   464  	t.Col("Age").MinIndex() -> 0
   465  */
   466  func (c *Column) MinIndex() int {
   467  	return fu.MinIndex(c.column)
   468  }
   469  
   470  /*
   471  Raw returns column internals
   472  */
   473  func (c *Column) Raw() (reflect.Value, fu.Bits) {
   474  	return c.column, c.na
   475  }
   476  
   477  func (c *Column) IsFloat() bool {
   478  	t := c.Type()
   479  	return t.Kind() == reflect.Float32 || t.Kind() == reflect.Float64
   480  }
   481  
   482  func (c *Column) Matrix(docopy ...bool) [][]float32 {
   483  	if c.Type() != fu.TensorType {
   484  		panic(zorros.Panic(zorros.New("column type is not tensor")))
   485  	}
   486  	t := c.Inspect().([]fu.Tensor)
   487  	r := make([][]float32, 0, len(t))
   488  	for _, x := range t {
   489  		r = append(r, x.Floats32(fu.Fnzb(docopy...)))
   490  	}
   491  	return r
   492  }