diff --git a/generic.go b/generic.go index 13c2534c2a4e7a53289650981b6128f0fc18d6af..381bc4ce74236394223be2f6ef58e7e5ebaad0d5 100644 --- a/generic.go +++ b/generic.go @@ -354,3 +354,27 @@ func (self *NDFrame) StdDev() float64 { stdDev := stat.StdDev(values, nil) return stdDev } + +func (self *NDFrame) FillNa(v any, inplace bool) { + values := self.Values() + switch rows := values.(type) { + case []string: + for idx, iv := range rows { + if StringIsNaN(iv) && inplace { + rows[idx] = AnyToString(v) + } + } + case []int64: + for idx, iv := range rows { + if IsNaN(float64(iv)) && inplace { + rows[idx] = AnyToInt64(v) + } + } + case []float64: + for idx, iv := range rows { + if IsNaN(iv) && inplace { + rows[idx] = AnyToFloat64(v) + } + } + } +} diff --git a/generic_test.go b/generic_test.go index 5c5393f2c4a3bc3fca537e810eaa145a8b15b7c9..5672e6bc6d506c2c85cf96ca62777a65021832b5 100644 --- a/generic_test.go +++ b/generic_test.go @@ -74,6 +74,7 @@ func TestNDFrameNew(t *testing.T) { // string d2 := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "nan", "12"} nd2 := NewNDFrame[string]("x", d2...) + nd2.FillNa(0, true) fmt.Println(nd2) fmt.Println(nd2.Records()) fmt.Println(nd2.Empty()) diff --git a/series.go b/series.go index 279efa81e01e0706d76668efa33cec88cd104f19..3bfa2eb4fe65c569ab28c6c29e55ba7e757326b8 100644 --- a/series.go +++ b/series.go @@ -56,6 +56,8 @@ type Series interface { Mean() float64 // StdDev calculates the standard deviation of a series StdDev() float64 + // FillNa Fill NA/NaN values using the specified method. + FillNa(v any, inplace bool) } // NewSeries 指定类型创建序列 @@ -193,3 +195,25 @@ func Shift[T GenericType](s *Series, periods int, cbNan func() T) Series { _ = naVals return d } + +// FillNa 填充NaN的元素为v +// inplace为真是修改series元素的值 +// 如果v和Values()返回值的slice类型不一致就会panic +func FillNa[T GenericType](s *NDFrame, v T, inplace bool) *NDFrame { + values := s.Values() + switch rows := values.(type) { + case []string: + for idx, iv := range rows { + if StringIsNaN(iv) && inplace { + rows[idx] = AnyToString(v) + } + } + case []float64: + for idx, iv := range rows { + if IsNaN(iv) && inplace { + rows[idx] = AnyToFloat64(v) + } + } + } + return s +} diff --git a/series_bool.go b/series_bool.go index 89cd78352eb5a90326e84ffe2a9e7afc3909ac56..aae892a102392ca2ea2cc02746f3b5cad2e4c60a 100644 --- a/series_bool.go +++ b/series_bool.go @@ -159,3 +159,16 @@ func (self *SeriesBool) StdDev() float64 { //TODO implement me panic("implement me") } + +// FillNa bool类型不可能在导入series还是NaN +func (self *SeriesBool) FillNa(v any, inplace bool) { + //values := self.Values() + //switch rows := values.(type) { + //case []bool: + // for idx, iv := range rows { + // if IsNaN(float64(iv)) && inplace { + // rows[idx] = AnyToFloat64(v) + // } + // } + //} +} diff --git a/series_float64.go b/series_float64.go index 90c18eca766ce9db87db7f246a5dc672fb885ba8..4f2a4fa2f020c5e81778dbc651ac29183f1bd92e 100644 --- a/series_float64.go +++ b/series_float64.go @@ -221,3 +221,15 @@ func (self *SeriesFloat64) StdDev() float64 { stdDev := stat.StdDev(values, nil) return stdDev } + +func (self *SeriesFloat64) FillNa(v any, inplace bool) { + values := self.Values() + switch rows := values.(type) { + case []float64: + for idx, iv := range rows { + if IsNaN(iv) && inplace { + rows[idx] = AnyToFloat64(v) + } + } + } +} diff --git a/series_int64.go b/series_int64.go index 2f117907451a92b7a8c6944b88a1b1e92c833b5e..588020963c6799085c1c9022a969db97b95e05e6 100644 --- a/series_int64.go +++ b/series_int64.go @@ -178,3 +178,16 @@ func (self *SeriesInt64) StdDev() float64 { stdDev := stat.StdDev(d, nil) return stdDev } + +// FillNa int64没有NaN +func (self *SeriesInt64) FillNa(v any, inplace bool) { + values := self.Values() + switch rows := values.(type) { + case []int64: + for idx, iv := range rows { + if IsNaN(float64(iv)) && inplace { + rows[idx] = AnyToInt64(v) + } + } + } +} diff --git a/series_xstring.go b/series_xstring.go index c149cef21ab759c629f5abc6077958ca74905f96..063c4c2cfe08e42e0c1bb96103eec5466210b0b4 100644 --- a/series_xstring.go +++ b/series_xstring.go @@ -164,3 +164,15 @@ func (self *SeriesString) StdDev() float64 { //TODO implement me panic("implement me") } + +func (self *SeriesString) FillNa(v any, inplace bool) { + values := self.Values() + switch rows := values.(type) { + case []string: + for idx, iv := range rows { + if StringIsNaN(iv) && inplace { + rows[idx] = AnyToString(v) + } + } + } +} diff --git a/type_bool.go b/type_bool.go index 44803ddfe2ef562bf132d4393cd7855b88f888b0..b0a546fad9fb5aafd57b5c30c214183c286726fc 100644 --- a/type_bool.go +++ b/type_bool.go @@ -85,7 +85,7 @@ func AnyToBool(v any) bool { } } -// ParseFloat 字符串转float64 +// ParseBool 字符串转bool // 任意组合的nan字符串都会被解析成NaN func ParseBool(s string, v any) bool { f, err := strconv.ParseBool(s)