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 }