go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/tables/table.go (about) 1 // 2 // Package tables implements immutable tables abstraction 3 // 4 package tables 5 6 import ( 7 "fmt" 8 "go-ml.dev/pkg/base/fu" 9 "go-ml.dev/pkg/base/fu/lazy" 10 "golang.org/x/xerrors" 11 "math/bits" 12 "math/rand" 13 "reflect" 14 ) 15 16 /* 17 Table implements column based typed data structure 18 Every values in a column has the same type. 19 */ 20 type Table struct{ raw Raw } 21 22 /* 23 Raw is the row presentation of a table, can be accessed by the Table.Raw method 24 */ 25 type Raw struct { 26 Names []string 27 Columns []reflect.Value 28 Na []fu.Bits 29 Length int 30 } 31 32 /* 33 IsLazy returns false, because Table is not lazy 34 it's the tables.AnyData interface implementation 35 */ 36 func (*Table) IsLazy() bool { return false } 37 38 /* 39 Table returns self, because Table is a table 40 it's the tables.AnyData interface implementation 41 */ 42 func (t *Table) Table() *Table { return t } 43 44 /* 45 Collect returns self, because Table is a table 46 it's the tables.AnyData interface implementation 47 */ 48 func (t *Table) Collect() (*Table, error) { return t, nil } 49 50 /* 51 Lazy returns new lazy stream sourcing from the table 52 it's the tables.AnyData interface implementation 53 */ 54 func (t *Table) Lazy() Lazy { 55 return func() lazy.Stream { 56 flag := &fu.AtomicFlag{Value: 1} 57 return func(index uint64) (v reflect.Value, err error) { 58 if index == lazy.STOP { 59 flag.Clear() 60 } else if flag.State() && index < uint64(t.raw.Length) { 61 return reflect.ValueOf(t.Index(int(index))), nil 62 } 63 return reflect.ValueOf(false), nil 64 } 65 } 66 } 67 68 /* 69 Col returns Column object for the table' column selected by the name 70 71 t := tables.New([]struct{Name string; Age int; Rate float32}{{"Ivanov",42,1.2},{"Petrov",42,1.5}}) 72 t.Col("Name").String(0) -> "Ivanov" 73 t.Col("Name").Len() -> 2 74 */ 75 func (t *Table) Col(c string) *Column { 76 for i, n := range t.raw.Names { 77 if n == c { 78 return &Column{t.raw.Columns[i], t.raw.Na[i]} 79 } 80 } 81 panic("there is not column with name " + c) 82 } 83 84 func (t *Table) ColIfExists(c string) (*Column, bool) { 85 for i, n := range t.raw.Names { 86 if n == c { 87 return &Column{t.raw.Columns[i], t.raw.Na[i]}, true 88 } 89 } 90 return nil, false 91 } 92 93 /* 94 Raw returns raw table structure 95 */ 96 func (t *Table) Raw() Raw { 97 return t.raw 98 } 99 100 /* 101 Len returns count of table rows 102 */ 103 func (t *Table) Len() int { 104 return t.raw.Length 105 } 106 107 func (t *Table) FilteredLen(f func(int) bool) int { 108 if f != nil { 109 L := 0 110 for i := 0; i < t.raw.Length; i++ { 111 if f(i) { 112 L++ 113 } 114 } 115 return L 116 } 117 return t.Len() 118 } 119 120 /* 121 Names returns list of column Names 122 */ 123 func (t *Table) Names() []string { 124 r := make([]string, len(t.raw.Names), len(t.raw.Names)) 125 copy(r, t.raw.Names) 126 return r 127 } 128 129 /* 130 Empty creates new empty table 131 */ 132 func Empty() *Table { 133 t := &Table{} 134 return t 135 } 136 137 /* 138 MakeTable creates ne non-empty table 139 */ 140 func MakeTable(names []string, columns []reflect.Value, na []fu.Bits, length int) *Table { 141 return &Table{ 142 raw: Raw{ 143 Names: names, 144 Columns: columns, 145 Na: na, 146 Length: length}, 147 } 148 } 149 150 /* 151 New creates new Table object 152 153 - from empty list of structs or empty struct 154 tables.New([]struct{Name string; Age int; Rate float32}{}) 155 for empty table. 156 157 - from list of structs 158 tables.New([]struct{Name string; Age int; Rate float32}{{"Ivanov",32,1.2},{"Petrov",44,1.5}}) 159 160 - from map 161 tables.New(map[string]interface{}{"Name":[]string{"Ivanov","Petrov"},"Age":[]int{32,44},"Rate":[]float32{1.2,1.5}}) 162 163 - from channel of structs 164 type R struct{Name string; Age int; Rate float32} 165 c := make(chan R) 166 go func(){ 167 c <- R{"Ivanov",32,1.2} 168 c <- R{"Petrov",44,1.5} 169 close(c) 170 }() 171 tables.New(c) 172 */ 173 func New(o interface{}) *Table { 174 175 q := reflect.ValueOf(o) 176 177 switch q.Kind() { 178 case reflect.Slice: // New([]struct{}{{}}) 179 l := q.Len() 180 tp := q.Type().Elem() 181 if tp.Kind() != reflect.Struct && !(tp.Kind() == reflect.Ptr && tp.Elem().Kind() == reflect.Struct) { 182 panic("slice of structures allowed only") 183 } 184 185 if l > 0 && (tp == fu.StructType) { 186 // New([]mlutil.Struct{{}}) 187 lrx := q.Interface().([]fu.Struct) 188 names := lrx[0].Names 189 columns := make([]reflect.Value, len(names)) 190 for i := range columns { 191 columns[i] = reflect.MakeSlice(reflect.SliceOf(lrx[0].Columns[i].Type()), l, l) 192 } 193 na := make([]fu.Bits, len(names)) 194 for i := range names { 195 for j := 0; j < l; j++ { 196 columns[i].Index(j).Set(lrx[j].Columns[i]) 197 na[i].Set(j, lrx[j].Na.Bit(i)) 198 } 199 } 200 return MakeTable(names, columns, make([]fu.Bits, len(names)), l) 201 } 202 203 if l > 0 && (tp.Kind() == reflect.Ptr && tp.Elem() == fu.StructType) { 204 // New([]*mlutil.Struct{{}}) 205 lrx := q.Interface().([]*fu.Struct) 206 names := lrx[0].Names 207 columns := make([]reflect.Value, len(names)) 208 for i := range columns { 209 columns[i] = reflect.MakeSlice(reflect.SliceOf(lrx[0].Columns[i].Type()), l, l) 210 } 211 na := make([]fu.Bits, len(names)) 212 for i := range names { 213 for j := 0; j < l; j++ { 214 columns[i].Index(j).Set(lrx[j].Columns[i]) 215 na[i].Set(j, lrx[j].Na.Bit(i)) 216 } 217 } 218 return MakeTable(names, columns, make([]fu.Bits, len(names)), l) 219 } 220 221 if tp.Kind() == reflect.Ptr { 222 tp = tp.Elem() 223 } 224 225 nl := tp.NumField() 226 names := make([]string, 0, nl) 227 columns := make([]reflect.Value, 0, nl) 228 for i := 0; i < nl; i++ { 229 fv := tp.Field(i) 230 names = append(names, fv.Name) 231 col := reflect.MakeSlice(reflect.SliceOf(fv.Type), l, l) 232 columns = append(columns, col) 233 for j := 0; j < l; j++ { 234 x := q.Index(j) 235 if x.Kind() == reflect.Ptr { 236 x = x.Elem() 237 } 238 col.Index(j).Set(x.Field(i)) 239 } 240 } 241 242 return MakeTable(names, columns, make([]fu.Bits, len(names)), l) 243 244 case reflect.Chan: // New(chan struct{}) 245 tp := q.Type().Elem() 246 nl := tp.NumField() 247 names := make([]string, nl) 248 columns := make([]reflect.Value, nl) 249 scase := []reflect.SelectCase{{Dir: reflect.SelectRecv, Chan: q}} 250 251 for i := 0; i < nl; i++ { 252 fv := tp.Field(i) 253 names[i] = fv.Name 254 columns[i] = reflect.MakeSlice(reflect.SliceOf(fv.Type), 0, 1) 255 } 256 257 length := 0 258 for { 259 _, v, ok := reflect.Select(scase) 260 if !ok { 261 break 262 } 263 for i := 0; i < nl; i++ { 264 columns[i] = reflect.Append(columns[i], v.Field(i)) 265 } 266 length++ 267 } 268 269 return MakeTable(names, columns, make([]fu.Bits, len(names)), length) 270 271 case reflect.Map: // New(map[string]interface{}{}) 272 m := o.(map[string]interface{}) 273 names := fu.SortedKeysOf(m).([]string) 274 columns := make([]reflect.Value, len(names), len(names)) 275 l := reflect.ValueOf(m[names[0]]).Len() 276 277 for i, n := range names { 278 vals := reflect.ValueOf(m[n]) 279 if vals.Len() != l { 280 panic("bad count of elements in column " + n) 281 } 282 columns[i] = reflect.MakeSlice(vals.Type() /*[]type*/, l, l) 283 reflect.Copy(columns[i], vals) 284 } 285 286 return MakeTable(names, columns, make([]fu.Bits, len(names)), l) 287 } 288 289 panic("bad argument type") 290 } 291 292 func NewEmpty(names []string, types []reflect.Type) *Table { 293 columns := make([]reflect.Value, len(names)) 294 if types != nil { 295 for i := range columns { 296 columns[i] = reflect.MakeSlice(reflect.SliceOf(types[i]), 0, 0) 297 } 298 } else { 299 for i := range columns { 300 columns[i] = reflect.MakeSlice(reflect.SliceOf(fu.InterfaceType), 0, 0) 301 } 302 } 303 return MakeTable(names, columns, make([]fu.Bits, len(names)), 0) 304 } 305 306 /* 307 Slice takes a row slice from table 308 309 t := tables.New([]struct{Name string; Age int; Rate float32}{{"Ivanov",32,1.2},{"Petrov",44,1.5}}) 310 t.Slice(0).Row(0) -> {"Ivanov",32,1.2} 311 t.Slice(1).Row(0) -> {"Petrov",44,1.5} 312 t.Slice(0,2).Len() -> 2 313 t.Slice(1,2).Len() -> 1 314 */ 315 func (t *Table) Slice(slice ...int) *Table { 316 from, to := 0, t.raw.Length 317 if len(slice) > 0 { 318 from = slice[0] 319 to = from + 1 320 } 321 if len(slice) > 1 { 322 to = slice[1] 323 } 324 to, from = fu.Mini(to, t.raw.Length), fu.Mini(from, t.raw.Length) 325 rv := make([]reflect.Value, len(t.raw.Columns)) 326 for i, v := range t.raw.Columns { 327 rv[i] = v.Slice(from, to) 328 } 329 na := make([]fu.Bits, len(t.raw.Columns)) 330 for i, x := range t.raw.Na { 331 na[i] = x.Slice(from, to) 332 } 333 return MakeTable(t.raw.Names, rv, na, to-from) 334 } 335 336 /* 337 Only takes specified Columns as new table 338 339 t := tables.New([]struct{Name string; Age int; Rate float32}{{"Ivanov",32,1.2},{"Petrov",44,1.5}}) 340 t2 := t.Only("Age","Rate") 341 t2.Names() -> ["Age", "Rate"] 342 t2.Row(0) -> {"Age": 32, "Rate": 1.2} 343 */ 344 func (t *Table) Only(column ...string) *Table { 345 rn := fu.Bits{} 346 for _, c := range column { 347 like := fu.Pattern(c) 348 for i, x := range t.raw.Names { 349 if like(x) { 350 rn.Set(i, true) 351 } 352 } 353 } 354 names := make([]string, 0, rn.Count()) 355 for i := range t.raw.Names { 356 if rn.Bit(i) { 357 names = append(names, t.raw.Names[i]) 358 } 359 } 360 rv := make([]reflect.Value, 0, len(names)) 361 na := make([]fu.Bits, 0, len(names)) 362 for i, v := range t.raw.Columns { 363 if rn.Bit(i) { 364 rv = append(rv, v.Slice(0, t.raw.Length)) 365 na = append(na, t.raw.Na[i]) 366 } 367 } 368 return MakeTable(names, rv, na, t.raw.Length) 369 } 370 371 func (t *Table) Except(column ...string) *Table { 372 rn := fu.Bits{} 373 for _, c := range column { 374 like := fu.Pattern(c) 375 for i, x := range t.raw.Names { 376 if like(x) { 377 rn.Set(i, true) 378 } 379 } 380 } 381 names := make([]string, 0, len(t.raw.Names)-rn.Count()) 382 for i := range t.raw.Names { 383 if !rn.Bit(i) { 384 names = append(names, t.raw.Names[i]) 385 } 386 } 387 rv := make([]reflect.Value, 0, len(names)) 388 na := make([]fu.Bits, 0, len(names)) 389 for i, v := range t.raw.Columns { 390 if !rn.Bit(i) { 391 rv = append(rv, v.Slice(0, t.raw.Length)) 392 na = append(na, t.raw.Na[i]) 393 } 394 } 395 return MakeTable(names, rv, na, t.raw.Length) 396 } 397 398 func (t *Table) OnlyNames(column ...string) []string { 399 rn := fu.Bits{} 400 for _, c := range column { 401 like := fu.Pattern(c) 402 for i, x := range t.raw.Names { 403 if like(x) { 404 rn.Set(i, true) 405 } 406 } 407 } 408 names := make([]string, 0, rn.Count()) 409 for i := range t.raw.Names { 410 if rn.Bit(i) { 411 names = append(names, t.raw.Names[i]) 412 } 413 } 414 return names 415 } 416 417 /* 418 Append adds data to table 419 420 t := tables.Empty() 421 422 - from list of structs 423 t = t.Append([]struct{Name string; Age int; Rate: float32}{{"Ivanov",32,1.2},{"Petrov",44,1.5}}) 424 - from map of values 425 t = t.Append(map[string]interface{}{"Name":[]string{"Ivanov","Petrov"},"Age":[]int{32,44},"Rate":[]float32{1.2,1.5}}) 426 427 - from channel 428 type R struct{Name string; Age int; Rate float32} 429 c := make(chan R) 430 go func(){ 431 c <- R{"Ivanov",32,1.2} 432 c <- R{"Petrov",44,1.5} 433 close(c) 434 }() 435 t.Append(c) 436 437 Or inserts empty column 438 - by empty list of structs 439 t = t.Append([]struct{Info string}{}) 440 - by map of values 441 t = t.Append(map[string]interface{}{"Info":[]string{}) 442 443 */ 444 func (t *Table) Append(o interface{}) *Table { 445 return Concat(t, New(o)) 446 } 447 448 /* 449 Concat concats two tables into new one 450 451 t1 := tables.New(struct{Name string; Age int; Rate float32}{"Ivanov",32,1.2}) 452 t2 := tables.New(struct{Name string; Age int; Rate float32}{"Petrov",44}) 453 q := t1.Concat(t2) 454 q.Row(0) -> {"Ivanov",32,1.2} 455 q.Row(1) -> {"Petrov",44,0} 456 */ 457 func (t *Table) Concat(a *Table) *Table { 458 /* names := t.Names() 459 columns := make([]reflect.Value, len(names), len(names)) 460 copy(columns, t.raw.Columns) 461 na := make([]fu.Bits, len(names)) 462 copy(na, t.raw.Na) 463 464 for i, n := range a.raw.Names { 465 j := fu.IndexOf(n, names) 466 if j < 0 { 467 col := reflect.MakeSlice(a.raw.Columns[i].Type(), t.raw.Length, t.raw.Length+a.raw.Length) 468 col = reflect.AppendSlice(col, a.raw.Columns[i]) 469 names = append(names, n) 470 columns = append(columns, col) 471 na = append(na, fu.FillBits(t.raw.Length).Append(a.raw.Na[i], t.raw.Length)) 472 } else { 473 columns[j] = reflect.AppendSlice(columns[j], a.raw.Columns[i]) 474 na[j] = na[j].Append(a.raw.Na[i], t.raw.Length) 475 } 476 } 477 478 for i, col := range columns { 479 if col.Len() < a.raw.Length+t.raw.Length { 480 columns[i] = reflect.AppendSlice( 481 col, 482 reflect.MakeSlice(col.Type(), a.raw.Length, a.raw.Length)) 483 na[i] = na[i].Append(fu.FillBits(a.raw.Length), t.raw.Length) 484 } 485 } 486 487 return MakeTable(names, columns, na, a.raw.Length+t.raw.Length) */ 488 return Concat(t, a) 489 } 490 491 /* 492 List executes function for every row 493 494 t := tables.New([]struct{Name string; Age int; Rate float32}{{"Ivanov",32,1.2},{"Petrov",44,1.5}}) 495 t.List(func(r struct{Rate float}, i int){ 496 fmt.Println(i, r.Rate) 497 }) 498 */ 499 func (t *Table) List(f interface{}) { 500 q := reflect.ValueOf(f) 501 tp := q.Type().In(0) 502 for i := 0; i < t.raw.Length; i++ { 503 iv := reflect.ValueOf(i) 504 q.Call([]reflect.Value{t.GetRow(i, tp), iv}) 505 } 506 } 507 508 /* 509 Sort sorts rows by specified Columns and returns new sorted table 510 511 t := tables.New([]struct{Name string; Age int; Rate float32}{{"Ivanov",32,1.2},{"Petrov",44,1.5}}) 512 t.Row(0) -> {Name: "Ivanov", "Age": 32, "Rate", 1.2} 513 q := t.Sort("Name",tables.DESC) 514 q.Row(0) -> {Name: "Petrov", "Age": 44, "Rate", 1.5} 515 */ 516 func (t *Table) Sort(opt interface{}) *Table { 517 return nil 518 } 519 520 /* 521 */ 522 func (t *Table) DropNa(names ...string) *Table { 523 var dx []int 524 if len(names) > 0 { 525 dx = make([]int, 0, len(names)) 526 for _, n := range names { 527 i := fu.IndexOf(n, t.raw.Names) 528 if i < 0 { 529 panic("does not have field " + n) 530 } 531 dx = append(dx, i) 532 } 533 } else { 534 dx = make([]int, len(t.raw.Names)) 535 for i := range t.raw.Names { 536 dx[i] = i 537 } 538 } 539 rc := t.raw.Length 540 wc := fu.Words(t.raw.Length) 541 for j := 0; j < wc; j++ { 542 w := uint(0) 543 for _, i := range dx { 544 w |= t.raw.Na[i].Word(j) 545 } 546 rc -= bits.OnesCount(w) 547 } 548 if rc == t.raw.Length { 549 return t 550 } 551 na := make([]fu.Bits, len(t.raw.Columns)) 552 columns := make([]reflect.Value, len(t.raw.Columns)) 553 for i := range t.raw.Columns { 554 columns[i] = reflect.MakeSlice(t.raw.Columns[i].Type(), rc, rc) 555 } 556 k := 0 557 for j := 0; j < t.raw.Length; j++ { 558 b := false 559 for _, i := range dx { 560 b = b || t.raw.Na[i].Bit(j) 561 } 562 if b { 563 continue 564 } 565 for i := range t.raw.Columns { 566 columns[i].Index(k).Set(t.raw.Columns[i].Index(j)) 567 na[i].Set(k, t.raw.Na[i].Bit(j)) 568 } 569 k++ 570 } 571 return MakeTable(t.raw.Names, columns, na, rc) 572 } 573 574 func (t *Table) FillNa(r interface{}) *Table { 575 var m map[string]interface{} 576 v := reflect.ValueOf(r) 577 if v.Kind() != reflect.Struct && v.Kind() != reflect.Map { 578 panic("only struct{...} or map[string]interface{} are allowed as an argument") 579 } 580 581 if v.Kind() == reflect.Struct { 582 m = map[string]interface{}{} 583 n := v.NumField() 584 ft := v.Type() 585 for i := 0; i < n; i++ { 586 f := ft.Field(i) 587 m[f.Name] = v.Field(i).Interface() 588 } 589 } else { 590 m = r.(map[string]interface{}) 591 } 592 593 columns := make([]reflect.Value, len(t.raw.Columns)) 594 na := make([]fu.Bits, len(t.raw.Columns)) 595 for n, x := range m { 596 j := fu.IndexOf(n, t.raw.Names) 597 if j < 0 { 598 panic(" table does not have column " + n) 599 } 600 if t.raw.Na[j].Len() == 0 { 601 columns[j] = t.raw.Columns[j] 602 } else { 603 y := reflect.ValueOf(x) 604 vt := t.raw.Columns[j].Type().Elem() 605 if vt != y.Type() { 606 if vt.Kind() == reflect.String { 607 y = reflect.ValueOf(fmt.Sprint(x)) 608 } else { 609 y = y.Convert(vt) 610 } 611 } 612 columns[j] = reflect.MakeSlice(t.raw.Columns[j].Type(), t.raw.Length, t.raw.Length) 613 reflect.Copy(columns[j], t.raw.Columns[j]) 614 for k := 0; k < t.raw.Length; k++ { 615 if t.raw.Na[j].Bit(k) { 616 columns[j].Index(k).Set(y) 617 } 618 } 619 } 620 } 621 for i := range columns { 622 if !columns[i].IsValid() { 623 columns[i] = t.raw.Columns[i] 624 na[i] = t.raw.Na[i] 625 } 626 } 627 628 return MakeTable(t.raw.Names, columns, na, t.raw.Length) 629 } 630 631 func (t *Table) Index(r int) fu.Struct { 632 names := t.raw.Names 633 columns := make([]reflect.Value, len(names)) 634 na := fu.Bits{} 635 for i, c := range t.raw.Columns { 636 columns[i] = c.Index(r) 637 na.Set(i, t.raw.Na[i].Bit(r)) 638 } 639 return fu.Struct{names, columns, na} 640 } 641 642 func (t *Table) Last(n ...int) fu.Struct { 643 k := 1 644 if len(n) > 0 { 645 k = n[0] + 1 646 } 647 return t.Index(t.Len() - k) 648 } 649 650 func (t *Table) With(column *Column, name string) *Table { 651 if column.Len() != t.raw.Length { 652 panic(xerrors.Errorf("column length is not match table length")) 653 } 654 if fu.IndexOf(name, t.raw.Names) >= 0 { 655 panic(xerrors.Errorf("column with name `%v` alreday exists in the table", name)) 656 } 657 names := make([]string, len(t.raw.Names), len(t.raw.Names)+1) 658 columns := make([]reflect.Value, len(t.raw.Names), len(t.raw.Names)+1) 659 na := make([]fu.Bits, len(t.raw.Names), len(t.raw.Names)+1) 660 copy(names, t.raw.Names) 661 copy(columns, t.raw.Columns) 662 copy(na, t.raw.Na) 663 names = append(names, name) 664 columns = append(columns, column.column) 665 na = append(na, column.na) 666 return MakeTable(names, columns, na, t.raw.Length) 667 } 668 669 func (t *Table) Without(name string) *Table { 670 names := make([]string, 0, len(t.raw.Names)) 671 columns := make([]reflect.Value, 0, len(t.raw.Names)) 672 na := make([]fu.Bits, 0, len(t.raw.Names)) 673 for i, n := range t.raw.Names { 674 if n != name { 675 names = append(names, n) 676 columns = append(columns, t.raw.Columns[i]) 677 na = append(na, t.raw.Na[i]) 678 } 679 } 680 return MakeTable(names, columns, na, t.raw.Length) 681 } 682 683 func (t *Table) Round(prec int /*, columns ...string*/) *Table { 684 return t.Lazy().Round(prec).LuckyCollect() 685 } 686 687 /* 688 func Shape(x interface{}, names ...string) *Table { 689 v := reflect.ValueOf(x) 690 vt := v.Type() 691 if v.Kind() != reflect.Slice { 692 panic(xerrors.Errorf("only []any allowed as the first argument")) 693 } 694 width := len(names) 695 length := v.Len() / width 696 columns := make([]reflect.Value, width) 697 na := make([]mlutil.Bits, width) 698 for i := range names { 699 columns[i] = reflect.MakeSlice(reflect.SliceOf(vt), length, length) 700 for j := 0; j < length; j++ { 701 y := v.Index(j*width + i) 702 na[i].Set(j, mlutil.Isna(y)) 703 columns[i].Index(j).Set(y) 704 } 705 } 706 return MakeTable(names, columns, na, length) 707 } 708 709 func Shape32f(v []float32, names ...string) *Table { 710 width := len(names) 711 length := len(v) / width 712 columns := make([]reflect.Value, width) 713 na := make([]mlutil.Bits, width) 714 for i := range names { 715 ls := make([]float32, length) 716 for j := 0; j < length; j++ { 717 y := v[j*width+i] 718 na[i].Set(j, math.IsNaN(float64(y))) 719 ls[j] = y 720 } 721 columns[i] = reflect.ValueOf(ls) 722 } 723 return MakeTable(names, columns, na, length) 724 } 725 */ 726 727 func Concat(x ...*Table) *Table { 728 l := 0 729 names := []string{} 730 columns := []reflect.Value{} 731 na := []fu.Bits{} 732 733 for _, a := range x { 734 for i, n := range a.raw.Names { 735 j := fu.IndexOf(n, names) 736 if j < 0 { 737 col := reflect.MakeSlice(a.raw.Columns[i].Type() /*[]type*/, l, l+a.raw.Length) 738 col = reflect.AppendSlice(col, a.raw.Columns[i]) 739 names = append(names, n) 740 columns = append(columns, col) 741 na = append(na, fu.FillBits(l).Append(a.raw.Na[i], l)) 742 } else { 743 columns[j] = reflect.AppendSlice(columns[j], a.raw.Columns[i]) 744 na[j] = na[j].Append(a.raw.Na[i], l) 745 } 746 } 747 748 for i, col := range columns { 749 if col.Len() < a.raw.Length+l { 750 columns[i] = reflect.AppendSlice( 751 col, 752 reflect.MakeSlice(col.Type(), a.raw.Length, a.raw.Length)) 753 na[i] = na[i].Append(fu.FillBits(a.raw.Length), l) 754 } 755 } 756 757 l += a.raw.Length 758 } 759 760 return MakeTable(names, columns, na, l) 761 } 762 763 func (t *Table) Set(c string, value interface{}) *Table { 764 v := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(value)), t.Len(), t.Len()) 765 vx := reflect.ValueOf(value) 766 for i := 0; i < v.Len(); i++ { 767 v.Index(i).Set(vx) 768 } 769 names := make([]string, len(t.raw.Names), len(t.raw.Names)+1) 770 columns := make([]reflect.Value, len(t.raw.Names), len(t.raw.Names)+1) 771 na := make([]fu.Bits, len(t.raw.Names), len(t.raw.Names)+1) 772 copy(names, t.raw.Names) 773 copy(columns, t.raw.Columns) 774 copy(na, t.raw.Na) 775 if j := fu.IndexOf(c, t.raw.Names); j >= 0 { 776 columns[j] = v 777 na[j] = fu.Bits{} 778 } else { 779 names = append(names, c) 780 columns = append(columns, v) 781 na = append(na, fu.Bits{}) 782 } 783 return MakeTable(names, columns, na, t.raw.Length) 784 } 785 786 func (t *Table) Shuffle() *Table { 787 columns := make([]reflect.Value, len(t.raw.Columns)) 788 na := make([]fu.Bits, len(t.raw.Columns)) 789 for i, c := range t.raw.Columns { 790 columns[i] = reflect.MakeSlice(c.Type(), c.Len(), c.Len()) 791 } 792 for i, n := range rand.Perm(t.raw.Length) { 793 for j, c := range t.raw.Columns { 794 columns[j].Index(n).Set(c.Index(i)) 795 na[j].Set(n, t.raw.Na[j].Bit(i)) 796 } 797 } 798 return MakeTable(t.raw.Names, columns, na, t.raw.Length) 799 }