diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 603a03f6b..240ebfc74 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -14,7 +14,7 @@ jobs: - name: Install latest Rust nightly uses: dtolnay/rust-toolchain@stable with: - toolchain: nightly-2023-07-27 + toolchain: nightly-2023-11-15 components: rustfmt, clippy - name: Install ghp-import uses: actions/setup-python@v4 diff --git a/.github/workflows/test-js.yaml b/.github/workflows/test-js.yaml index 9a25a2d73..f48368f52 100644 --- a/.github/workflows/test-js.yaml +++ b/.github/workflows/test-js.yaml @@ -18,7 +18,7 @@ jobs: - name: Install latest Rust nightly uses: dtolnay/rust-toolchain@stable with: - toolchain: nightly-2023-07-27 + toolchain: nightly-2023-11-15 components: rustfmt, clippy - run: yarn --version - name: Install Node Dependencies @@ -43,7 +43,7 @@ jobs: - name: Install latest Rust nightly uses: dtolnay/rust-toolchain@stable with: - toolchain: nightly-2023-07-27 + toolchain: nightly-2023-11-15 components: rustfmt, clippy - name: Bun version uses: oven-sh/setup-bun@v1 diff --git a/Cargo.toml b/Cargo.toml index cbe6033a5..26dc0b1b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,13 +15,13 @@ crate-type = ["cdylib", "lib"] [dependencies] ahash = "0.8.3" bincode = "1.3.3" -napi = {version = "2.13.3", default-features = false, features = ["napi8", "serde-json", "experimental"]} -napi-derive = {version = "2.13.0", default-features = false} -polars-core = {git = "https://github.com/pola-rs/polars.git", rev = "60adaef43e1b3306d5da8cf736accea2e3f03d9b", default-features = false} -polars-io = {git = "https://github.com/pola-rs/polars.git", rev = "60adaef43e1b3306d5da8cf736accea2e3f03d9b", default-features = false} -polars-lazy = {git = "https://github.com/pola-rs/polars.git", rev = "60adaef43e1b3306d5da8cf736accea2e3f03d9b", default-features = false} +napi = {version = "2.14.1", default-features = false, features = ["napi8", "serde-json"]} +napi-derive = {version = "2.14.2", default-features = false} +polars-core = {git = "https://github.com/pola-rs/polars.git", rev = "b13afbecac039205dacbaca766ecca4bf441b347", default-features = false} +polars-io = {git = "https://github.com/pola-rs/polars.git", rev = "b13afbecac039205dacbaca766ecca4bf441b347", default-features = false} +polars-lazy = {git = "https://github.com/pola-rs/polars.git", rev = "b13afbecac039205dacbaca766ecca4bf441b347", default-features = false} thiserror = "1" -smartstring = { version = "1" } +smartstring = {version = "1"} serde_json = {version = "1"} either = "1.9" @@ -52,7 +52,6 @@ features = [ "concat_str", "row_hash", "reinterpret", - "decompress-fast", "mode", "extract_jsonpath", "lazy_regex", @@ -66,8 +65,6 @@ features = [ "diff", "pct_change", "moment", - "true_div", - "dtype-categorical", "diagonal_concat", "horizontal_concat", "abs", @@ -91,13 +88,14 @@ features = [ "arg_where", "timezones", "peaks", - "string_justify", + "string_pad", + "cov" ] git = "https://github.com/pola-rs/polars.git" -rev = "60adaef43e1b3306d5da8cf736accea2e3f03d9b" +rev = "b13afbecac039205dacbaca766ecca4bf441b347" [build-dependencies] -napi-build = "2.0.1" +napi-build = "2.1.0" [profile.release] codegen-units = 1 diff --git a/__tests__/dataframe.test.ts b/__tests__/dataframe.test.ts index fe02dd709..bb82beb98 100644 --- a/__tests__/dataframe.test.ts +++ b/__tests__/dataframe.test.ts @@ -1539,7 +1539,7 @@ describe("io", () => { test("writeCSV:string:header", () => { const actual = df .clone() - .writeCSV({ sep: "X", hasHeader: false }) + .writeCSV({ sep: "X", includeHeader: false }) .toString(); const expected = "1X6\n2X2\n9X8\n"; expect(actual).toEqual(expected); diff --git a/__tests__/expr.test.ts b/__tests__/expr.test.ts index 4c09c2730..ccc9cfc61 100644 --- a/__tests__/expr.test.ts +++ b/__tests__/expr.test.ts @@ -331,8 +331,8 @@ describe("expr", () => { }); test.each` args | hashValue - ${[0]} | ${6574965099265562227n} - ${[{ k0: 1n, k1: 1 }]} | ${6574965099265562227n} + ${[0]} | ${6340063056640878722n} + ${[{ k0: 1n, k1: 1 }]} | ${9788354747012366704n} `("$# hash", ({ args, hashValue }) => { const df = pl.DataFrame({ a: [1] }); const expected = pl.DataFrame({ hash: [hashValue] }); @@ -863,19 +863,19 @@ describe("expr", () => { "take:list": [1, 2, 2, 3], }); const actual = df.select( - col("a").take([0, 2, 3, 5]).as("take:array"), + col("a").gather([0, 2, 3, 5]).as("take:array"), col("a") - .take(lit([0, 1, 2, 3])) + .gather(lit([0, 1, 2, 3])) .as("take:list"), ); expect(actual).toFrameEqual(expected); }); - test("takeEvery", () => { + test("gatherEvery", () => { const df = pl.DataFrame({ a: [1, 1, 2, 2, 3, 3, 8, null, 1] }); const expected = pl.DataFrame({ everyother: [1, 2, 3, 8, 1], }); - const actual = df.select(col("a").takeEvery(2).as("everyother")); + const actual = df.select(col("a").gatherEvery(2).as("everyother")); expect(actual).toFrameEqual(expected); }); test("unique", () => { @@ -1391,6 +1391,21 @@ describe("expr.str", () => { }); }); describe("expr.lst", () => { + test("argMax", () => { + const s0 = pl.Series("a", [[1, 2, 3]]); + let actual = s0.lst.argMax(); + let expected = pl.Series("a", [2]); + expect(actual.seriesEqual(expected)); + actual = s0.lst.argMin(); + expected = pl.Series("a", [0]); + expect(actual.seriesEqual(expected)); + }); + test("contains", () => { + const s0 = pl.Series("a", [[1, 2]]); + const actual = s0.lst.contains(1); + const expected = pl.Series("a", [true]); + expect(actual.seriesEqual(expected)); + }); test("concat", () => { const s0 = pl.Series("a", [[1, 2]]); const s1 = pl.Series("b", [[3, 4, 5]]); @@ -1422,6 +1437,12 @@ describe("expr.lst", () => { .seriesEqual(expected), ); }); + test("diff", () => { + const s0 = pl.Series("a", [[1, 2, 3]]); + const actual = s0.lst.diff(); + const expected = pl.Series("a", [null, 1, 1]); + expect(actual.seriesEqual(expected)); + }); test("get", () => { const df = pl.DataFrame({ a: [[1, 10, 11], [2, 10, 12], [1]] }); const expected = pl.DataFrame({ get: [11, 12, null] }); @@ -1448,6 +1469,12 @@ describe("expr.lst", () => { expect(actual).toFrameEqual(expected); expect(actualFromSeries).toFrameEqual(expected); }); + test("eval", () => { + const s0 = pl.Series("a", [[3, 5, 6]]); + const actual = s0.lst.eval(pl.element().rank()); + const expected = pl.Series("a", [1, 2, 3]); + expect(actual.seriesEqual(expected)); + }); test("first", () => { const df = pl.DataFrame({ a: [ @@ -1466,6 +1493,30 @@ describe("expr.lst", () => { expect(actual).toFrameEqual(expected); expect(actualFromSeries).toFrameEqual(expected); }); + test("head", () => { + const s0 = pl.Series("a", [[3, 5, 6, 7, 8]]); + let actual = s0.lst.head(1); + let expected = pl.Series("a", [3]); + expect(actual.seriesEqual(expected)); + actual = s0.lst.head(); + expected = pl.Series("a", [3, 5, 6, 7, 8]); + expect(actual.seriesEqual(expected)); + }); + test("tail", () => { + const s0 = pl.Series("a", [[3, 5, 6, 7, 8]]); + let actual = s0.lst.tail(1); + let expected = pl.Series("a", [8]); + expect(actual.seriesEqual(expected)); + actual = s0.lst.tail(); + expected = pl.Series("a", [3, 5, 6, 7, 8]); + expect(actual.seriesEqual(expected)); + }); + test("shift", () => { + const s0 = pl.Series("a", [[3, 5, 6]]); + const actual = s0.lst.shift(-1); + const expected = pl.Series("a", [5, 6, null]); + expect(actual.seriesEqual(expected)); + }); test("join", () => { const df = pl.DataFrame({ a: [["ab", "cd"], ["e", "fg"], ["h"]] }); const expected = pl.DataFrame({ joinedString: ["ab,cd", "e,fg", "h"] }); @@ -1630,16 +1681,13 @@ describe("expr.lst", () => { col("a").lst.sort().as("sort"), col("a").lst.sort({ reverse: true }).as("sort:reverse"), ); - const sortSeries = df.getColumn("a").lst.sort().rename("sort"); - const sortReverseSeries = df .getColumn("a") - .lst.sort(true) + .lst.sort({ reverse: true }) .rename("sort:reverse"); const actualFromSeries = pl.DataFrame([sortSeries, sortReverseSeries]); - expect(actual).toFrameEqual(expected); expect(actualFromSeries).toFrameEqual(expected); expect(actualFromSeries).toFrameEqual(actual); diff --git a/__tests__/lazyframe.test.ts b/__tests__/lazyframe.test.ts index a68493ac1..d729971f3 100644 --- a/__tests__/lazyframe.test.ts +++ b/__tests__/lazyframe.test.ts @@ -27,7 +27,6 @@ describe("lazyframe", () => { const actual = await expected.lazy().collect(); expect(actual).toFrameEqual(expected); }); - test("describeOptimizedPlan", () => { const df = pl .DataFrame({ @@ -35,10 +34,23 @@ describe("lazyframe", () => { bar: ["a", "b"], }) .lazy(); - const actual = df.describeOptimizedPlan().replace(/\s+/g, " "); - expect(actual).toEqual( - `DF ["foo", "bar"]; PROJECT */2 COLUMNS; SELECTION: "None"`, - ); + let actual = df.describeOptimizedPlan().replace(/\s+/g, " "); + const expected = `DF ["foo", "bar"]; PROJECT */2 COLUMNS; SELECTION: "None"`; + expect(actual).toEqual(expected); + actual = df.describePlan().replace(/\s+/g, " "); + expect(actual).toEqual(expected); + }); + test("cache", () => { + const df = pl.DataFrame({ + foo: [1, 2, 3], + }); + const expected = pl.DataFrame({ + foo: [1, 2, 3], + }); + let actual = df.lazy().cache().collectSync(); + expect(actual).toFrameEqual(expected); + actual = df.lazy().clone().collectSync(); + expect(actual).toFrameEqual(expected); }); test("drop", () => { const df = pl.DataFrame({ @@ -240,12 +252,10 @@ describe("lazyframe", () => { .lazy() .explode("list_1") .collectSync(); - const expected = pl.DataFrame({ letters: ["c", "c", "a", "a"], list_1: [1, 2, 1, 3], }); - expect(actual).toFrameEqualIgnoringOrder(expected); }); test("fetch", async () => { diff --git a/__tests__/series.test.ts b/__tests__/series.test.ts index 987a2bae4..41a01b3c2 100644 --- a/__tests__/series.test.ts +++ b/__tests__/series.test.ts @@ -409,8 +409,8 @@ describe("series", () => { ${numSeries()} | ${"sort"} | ${[{ reverse: false }]} ${numSeries()} | ${"sum"} | ${[]} ${numSeries()} | ${"tail"} | ${[]} - ${numSeries()} | ${"take"} | ${[[1, 2]]} - ${numSeries()} | ${"takeEvery"} | ${[1]} + ${numSeries()} | ${"gather"} | ${[[1, 2]]} + ${numSeries()} | ${"gatherEvery"} | ${[1]} ${numSeries()} | ${"toArray"} | ${[]} ${numSeries()} | ${"unique"} | ${[]} ${numSeries()} | ${"valueCounts"} | ${[]} @@ -472,7 +472,7 @@ describe("series", () => { ${"getIndex"} | ${pl.Series(["a", "b", "c"]).getIndex(0)} | ${"a"} ${"hasValidity"} | ${pl.Series([1, null, 2]).hasValidity()} | ${true} ${"hasValidity"} | ${pl.Series([1, 1, 2]).hasValidity()} | ${false} - ${"hash"} | ${pl.Series([1]).hash()} | ${pl.Series([6574965099265562227n])} + ${"hash"} | ${pl.Series([1]).hash()} | ${pl.Series([6340063056640878722n])} ${"head"} | ${pl.Series([1, 2, 3, 4, 5, 5, 5]).head()} | ${pl.Series([1, 2, 3, 4, 5])} ${"head"} | ${pl.Series([1, 2, 3, 4, 5, 5, 5]).head(2)} | ${pl.Series([1, 2])} ${"interpolate"} | ${pl.Series([1, 2, null, null, 5]).interpolate()} | ${pl.Series([1, 2, 3, 4, 5])} @@ -523,8 +523,8 @@ describe("series", () => { ${"sort"} | ${pl.Series([4, 2, 5, 0]).sort({ reverse: false })} | ${pl.Series([0, 2, 4, 5])} ${"sum"} | ${pl.Series([1, 2, 2, 1]).sum()} | ${6} ${"tail"} | ${pl.Series([1, 2, 2, 1]).tail(2)} | ${pl.Series([2, 1])} - ${"takeEvery"} | ${pl.Series([1, 3, 2, 9, 1]).takeEvery(2)} | ${pl.Series([1, 2, 1])} - ${"take"} | ${pl.Series([1, 3, 2, 9, 1]).take([0, 1, 3])} | ${pl.Series([1, 3, 9])} + ${"gatherEvery"} | ${pl.Series([1, 3, 2, 9, 1]).gatherEvery(2)} | ${pl.Series([1, 2, 1])} + ${"gather"} | ${pl.Series([1, 3, 2, 9, 1]).gather([0, 1, 3])} | ${pl.Series([1, 3, 9])} ${"toArray"} | ${pl.Series([1, 2, 3]).toArray()} | ${[1, 2, 3]} ${"unique"} | ${pl.Series([1, 2, 3, 3]).unique().sort()} | ${pl.Series([1, 2, 3])} ${"cumCount"} | ${pl.Series([1, 2, 3, 3]).cumCount()} | ${pl.Series([0, 1, 2, 3])} diff --git a/package.json b/package.json index d07f35676..a4e05665a 100644 --- a/package.json +++ b/package.json @@ -56,19 +56,19 @@ }, "devDependencies": { "@biomejs/biome": "^1.3.3", - "@napi-rs/cli": "^2.16.4", - "@types/chance": "^1.1.5", - "@types/jest": "^29.5.7", - "@types/node": "^20.8.10", + "@napi-rs/cli": "^2.16.5", + "@types/chance": "^1.1.6", + "@types/jest": "^29.5.10", + "@types/node": "^20.10.0", "chance": "^1.1.11", "jest": "^29.7.0", "source-map-support": "^0.5.21", "ts-jest": "^29.1.1", "ts-node": "^10.9.1", "typedoc": "^0.25.3", - "typescript": "5.2.2" + "typescript": "5.3.2" }, - "packageManager": "yarn@3.6.2", + "packageManager": "yarn@4.0.2", "workspaces": [ "benches" ] diff --git a/polars/lazy/expr/index.ts b/polars/lazy/expr/index.ts index 288055349..03d5718f8 100644 --- a/polars/lazy/expr/index.ts +++ b/polars/lazy/expr/index.ts @@ -559,10 +559,10 @@ export interface Expr * Take values by index. * @param index An expression that leads to a UInt32 dtyped Series. */ - take(index: Expr | number[] | Series): Expr; - take({ index }: { index: Expr | number[] | Series }): Expr; + gather(index: Expr | number[] | Series): Expr; + gather({ index }: { index: Expr | number[] | Series }): Expr; /** Take every nth value in the Series and return as a new Series. */ - takeEvery(n: number): Expr; + gatherEvery(n: number): Expr; /** * Get the unique values of this expression; * @param maintainOrder Maintain order of data. This requires more work. @@ -705,27 +705,27 @@ export const _Expr = (_expr: any): Expr => { cumCount(reverse: any = false) { reverse = reverse?.reverse ?? reverse; - return _Expr(_expr.cumcount(reverse?.reverse ?? reverse)); + return _Expr(_expr.cumCount(reverse?.reverse ?? reverse)); }, cumMax(reverse: any = false) { reverse = reverse?.reverse ?? reverse; - return _Expr(_expr.cummax(reverse)); + return _Expr(_expr.cumMax(reverse)); }, cumMin(reverse: any = false) { reverse = reverse?.reverse ?? reverse; - return _Expr(_expr.cummin(reverse)); + return _Expr(_expr.cumMin(reverse)); }, cumProd(reverse: any = false) { reverse = reverse?.reverse ?? reverse; - return _Expr(_expr.cumprod(reverse)); + return _Expr(_expr.cumProd(reverse)); }, cumSum(reverse: any = false) { reverse = reverse?.reverse ?? reverse; - return _Expr(_expr.cumsum(reverse)); + return _Expr(_expr.cumSum(reverse)); }, diff(n, nullBehavior = "ignore") { if (typeof n === "number") { @@ -1124,7 +1124,7 @@ export const _Expr = (_expr: any): Expr => { } }, shift(periods) { - return _Expr(_expr.shift(periods)); + return _Expr(_expr.shift(exprToLitOrExpr(periods)._expr)); }, shiftAndFill(optOrPeriods, fillValue?) { if (typeof optOrPeriods === "number") { @@ -1182,24 +1182,21 @@ export const _Expr = (_expr: any): Expr => { tail(length) { return _Expr(_expr.tail(length)); }, - - take(indices) { + gather(indices) { if (Array.isArray(indices)) { indices = pli.lit(Series(indices).inner()); } else { indices = indices.inner(); } - - return wrap("take", indices); + return wrap("gather", indices); }, - takeEvery(n) { - return _Expr(_expr.takeEvery(n)); + gatherEvery(n) { + return _Expr(_expr.gatherEvery(n)); }, unique(opt?) { if (opt || opt?.maintainOrder) { return wrap("uniqueStable"); } - return wrap("unique"); }, upperBound() { diff --git a/polars/lazy/expr/list.ts b/polars/lazy/expr/list.ts index 126a702da..3bc13330b 100644 --- a/polars/lazy/expr/list.ts +++ b/polars/lazy/expr/list.ts @@ -15,10 +15,10 @@ export const ExprListFunctions = (_expr: any): ExprList => { return { argMax() { - return wrap("lstArgMax"); + return wrap("listArgMax"); }, argMin() { - return wrap("lstArgMin"); + return wrap("listArgMin"); }, concat(other) { if ( @@ -42,7 +42,7 @@ export const ExprListFunctions = (_expr: any): ExprList => { return concatList(otherList); }, contains(item) { - throw new Error("not yet implemented"); + return wrap("listContains", exprToLitOrExpr(item)._expr); }, diff(n = 1, nullBehavior = "ignore") { return wrap("listDiff", n, nullBehavior); @@ -92,10 +92,14 @@ export const ExprListFunctions = (_expr: any): ExprList => { return wrap("listReverse"); }, shift(n) { - return wrap("listShift", n); + return wrap("listShift", exprToLitOrExpr(n)._expr); }, slice(offset, length) { - return wrap("listSlice", offset, length); + return wrap( + "listSlice", + exprToLitOrExpr(offset)._expr, + exprToLitOrExpr(length)._expr, + ); }, sort(reverse: any = false) { return typeof reverse === "boolean" diff --git a/polars/lazy/expr/string.ts b/polars/lazy/expr/string.ts index b4f07248b..f0ba44d85 100644 --- a/polars/lazy/expr/string.ts +++ b/polars/lazy/expr/string.ts @@ -24,7 +24,7 @@ export interface StringNamespace extends StringFunctions { * └──────────┘ * ``` */ - concat(delimiter: string): Expr; + concat(delimiter: string, ignoreNulls?: boolean): Expr; /** Check if strings in Series contain regex pattern. */ contains(pat: string | RegExp): Expr; /** @@ -317,8 +317,8 @@ export const ExprStringFunctions = (_expr: any): StringNamespace => { }; return { - concat(delimiter: string) { - return wrap("strConcat", delimiter); + concat(delimiter: string, ignoreNulls = true) { + return wrap("strConcat", delimiter, ignoreNulls); }, contains(pat: string | RegExp) { return wrap("strContains", regexToString(pat), false); diff --git a/polars/lazy/functions.ts b/polars/lazy/functions.ts index 619fa2b45..1c26c4a0a 100644 --- a/polars/lazy/functions.ts +++ b/polars/lazy/functions.ts @@ -318,11 +318,11 @@ export function count(column) { } /** Compute the covariance between two columns/ expressions. */ -export function cov(a: ExprOrString, b: ExprOrString): Expr { +export function cov(a: ExprOrString, b: ExprOrString, ddof = 1): Expr { a = exprToLitOrExpr(a, false); b = exprToLitOrExpr(b, false); - return _Expr(pli.cov(a, b)); + return _Expr(pli.cov(a, b, ddof)); } /** * Exclude certain columns from a wildcard expression. diff --git a/polars/series/index.ts b/polars/series/index.ts index 58914cefb..e179965ba 100644 --- a/polars/series/index.ts +++ b/polars/series/index.ts @@ -914,7 +914,7 @@ export interface Series * @example * ``` * s = pl.Series("a", [1, 2, 3, 4]) - * s.takeEvery(2)) + * s.gatherEvery(2)) * shape: (2,) * Series: '' [i64] * [ @@ -923,7 +923,7 @@ export interface Series * ] * ``` */ - takeEvery(n: number): Series; + gatherEvery(n: number): Series; /** * Take values by index. * ___ @@ -931,7 +931,7 @@ export interface Series * @example * ``` * s = pl.Series("a", [1, 2, 3, 4]) - * s.take([1, 3]) + * s.gather([1, 3]) * shape: (2,) * Series: 'a' [i64] * [ @@ -940,7 +940,7 @@ export interface Series * ] * ``` */ - take(indices: Array): Series; + gather(indices: Array): Series; /** * __Get unique elements in series.__ @@ -1201,16 +1201,16 @@ export function _Series(_s: any): Series { return expr_op("cumCount", reverse); }, cumSum(reverse?) { - return _Series(_s.cumsum(reverse)); + return _Series(_s.cumSum(reverse)); }, cumMax(reverse?) { - return _Series(_s.cummax(reverse)); + return _Series(_s.cumMax(reverse)); }, cumMin(reverse?) { - return _Series(_s.cummin(reverse)); + return _Series(_s.cumMin(reverse)); }, cumProd(reverse?) { - return _Series(_s.cumprod(reverse)); + return _Series(_s.cumProd(reverse)); }, describe() { let s = this.clone(); @@ -1677,11 +1677,11 @@ export function _Series(_s: any): Series { tail(length = 5) { return wrap("tail", length); }, - take(indices) { + gather(indices) { return wrap("take", indices); }, - takeEvery(n) { - return wrap("takeEvery", n); + gatherEvery(n) { + return wrap("gatherEvery", n); }, multiplyBy(field) { return this.mul(field); diff --git a/polars/series/string.ts b/polars/series/string.ts index 90d8480a7..070b5595b 100644 --- a/polars/series/string.ts +++ b/polars/series/string.ts @@ -16,7 +16,7 @@ export interface StringNamespace extends StringFunctions { * '1-null-2' * ``` */ - concat(delimiter: string): Series; + concat(delimiter: string, ignoreNulls?: boolean): Series; /** * Check if strings in Series contain regex pattern. * @param pattern A valid regex pattern @@ -271,10 +271,10 @@ export const SeriesStringFunctions = (_s: any): StringNamespace => { }; return { - concat(delimiter: string) { + concat(delimiter: string, ignoreNulls = true) { return _Series(_s) .toFrame() - .select(col(_s.name).str.concat(delimiter).as(_s.name)) + .select(col(_s.name).str.concat(delimiter, ignoreNulls).as(_s.name)) .getColumn(_s.name); }, contains(pat: string | RegExp) { diff --git a/polars/shared_traits.ts b/polars/shared_traits.ts index 584110fc8..a2540ec8b 100644 --- a/polars/shared_traits.ts +++ b/polars/shared_traits.ts @@ -640,7 +640,7 @@ export interface ListFunctions { * ``` * @category List */ - head(n: number): T; + head(n?: number): T; /** * Slice the tail of every sublist * @param n - How many values to take in the slice. @@ -657,7 +657,7 @@ export interface ListFunctions { * ``` * @category List */ - tail(n: number): T; + tail(n?: number): T; /** * Join all string items in a sublist and place a separator between them. * This errors if inner type of list `!= Utf8`. @@ -843,7 +843,7 @@ export interface StringFunctions { * └──────────┘ * ``` */ - concat(delimiter: string): T; + concat(delimiter: string, ignoreNulls?: boolean): T; /** Check if strings in Series contain regex pattern. */ contains(pat: string | RegExp): T; /** diff --git a/polars/types.ts b/polars/types.ts index c8d3812ae..a4711700c 100644 --- a/polars/types.ts +++ b/polars/types.ts @@ -43,7 +43,7 @@ export interface ConcatOptions { * @category Options */ export interface WriteCsvOptions { - hasHeader?: boolean; + includeHeader?: boolean; sep?: string; } diff --git a/rust-toolchain b/rust-toolchain index acd39859b..cc0696b17 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2023-10-12 \ No newline at end of file +nightly-2023-11-15 \ No newline at end of file diff --git a/src/conversion.rs b/src/conversion.rs index ebc7f90c3..20a7d45df 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -560,7 +560,7 @@ impl From for RowCount { #[napi(object)] pub struct WriteCsvOptions { - pub has_header: Option, + pub include_header: Option, pub sep: Option, pub quote: Option, } diff --git a/src/dataframe.rs b/src/dataframe.rs index a9e218fb8..0908ed5da 100644 --- a/src/dataframe.rs +++ b/src/dataframe.rs @@ -996,24 +996,24 @@ impl JsDataFrame { #[napi(catch_unwind)] pub fn hmean(&self, null_strategy: Wrap) -> napi::Result> { - let s = self.df.hmean(null_strategy.0).map_err(JsPolarsErr::from)?; + let s = self.df.mean_horizontal(null_strategy.0).map_err(JsPolarsErr::from)?; Ok(s.map(|s| s.into())) } #[napi(catch_unwind)] pub fn hmax(&self) -> napi::Result> { - let s = self.df.hmax().map_err(JsPolarsErr::from)?; + let s = self.df.max_horizontal().map_err(JsPolarsErr::from)?; Ok(s.map(|s| s.into())) } #[napi(catch_unwind)] pub fn hmin(&self) -> napi::Result> { - let s = self.df.hmin().map_err(JsPolarsErr::from)?; + let s = self.df.min_horizontal().map_err(JsPolarsErr::from)?; Ok(s.map(|s| s.into())) } #[napi(catch_unwind)] pub fn hsum(&self, null_strategy: Wrap) -> napi::Result> { - let s = self.df.hsum(null_strategy.0).map_err(JsPolarsErr::from)?; + let s = self.df.sum_horizontal(null_strategy.0).map_err(JsPolarsErr::from)?; Ok(s.map(|s| s.into())) } #[napi(catch_unwind)] @@ -1318,7 +1318,7 @@ impl JsDataFrame { options: WriteCsvOptions, env: Env, ) -> napi::Result<()> { - let has_header = options.has_header.unwrap_or(true); + let include_header = options.include_header.unwrap_or(true); let sep = options.sep.unwrap_or(",".to_owned()); let sep = sep.as_bytes()[0]; let quote = options.quote.unwrap_or(",".to_owned()); @@ -1332,7 +1332,7 @@ impl JsDataFrame { let f = std::fs::File::create(path).unwrap(); let f = BufWriter::new(f); CsvWriter::new(f) - .has_header(has_header) + .include_header(include_header) .with_separator(sep) .with_quote_char(quote) .finish(&mut self.df) @@ -1343,7 +1343,7 @@ impl JsDataFrame { let writeable = JsWriteStream { inner, env: &env }; CsvWriter::new(writeable) - .has_header(has_header) + .include_header(include_header) .with_separator(sep) .with_quote_char(quote) .finish(&mut self.df) diff --git a/src/lazy/dsl.rs b/src/lazy/dsl.rs index 401646e1b..5ced3c54c 100644 --- a/src/lazy/dsl.rs +++ b/src/lazy/dsl.rs @@ -341,8 +341,8 @@ impl JsExpr { self.clone().inner.arg_min().into() } #[napi(catch_unwind)] - pub fn take(&self, idx: &JsExpr) -> JsExpr { - self.clone().inner.take(idx.inner.clone()).into() + pub fn gather(&self, idx: &JsExpr) -> JsExpr { + self.clone().inner.gather(idx.inner.clone()).into() } #[napi(catch_unwind)] @@ -361,8 +361,8 @@ impl JsExpr { } #[napi(catch_unwind)] - pub fn shift(&self, periods: i64) -> JsExpr { - self.clone().inner.shift(periods).into() + pub fn shift(&self, periods: &JsExpr) -> JsExpr { + self.clone().inner.shift(periods.inner.clone()).into() } #[napi(catch_unwind)] @@ -446,14 +446,14 @@ impl JsExpr { self.clone().inner.explode().into() } #[napi(catch_unwind)] - pub fn take_every(&self, n: i64) -> JsExpr { + pub fn gather_every(&self, n: i64) -> JsExpr { self.clone() .inner .map( - move |s: Series| Ok(Some(s.take_every(n as usize))), + move |s: Series| Ok(Some(s.gather_every(n as usize))), GetOutput::same_type(), ) - .with_fmt("take_every") + .with_fmt("gather_every") .into() } #[napi(catch_unwind)] @@ -535,20 +535,20 @@ impl JsExpr { self.clone().inner.pow(exponent).into() } #[napi(catch_unwind)] - pub fn cumsum(&self, reverse: bool) -> JsExpr { - self.clone().inner.cumsum(reverse).into() + pub fn cum_sum(&self, reverse: bool) -> JsExpr { + self.clone().inner.cum_sum(reverse).into() } #[napi(catch_unwind)] - pub fn cummax(&self, reverse: bool) -> JsExpr { - self.clone().inner.cummax(reverse).into() + pub fn cum_max(&self, reverse: bool) -> JsExpr { + self.clone().inner.cum_max(reverse).into() } #[napi(catch_unwind)] - pub fn cummin(&self, reverse: bool) -> JsExpr { - self.clone().inner.cummin(reverse).into() + pub fn cum_min(&self, reverse: bool) -> JsExpr { + self.clone().inner.cum_min(reverse).into() } #[napi(catch_unwind)] - pub fn cumprod(&self, reverse: bool) -> JsExpr { - self.clone().inner.cumprod(reverse).into() + pub fn cum_prod(&self, reverse: bool) -> JsExpr { + self.clone().inner.cum_prod(reverse).into() } #[napi(catch_unwind)] @@ -649,7 +649,7 @@ impl JsExpr { let function = move |s: Series| { let ca = s.utf8()?; Ok(Some( - ca.rjust(length as usize, fill_char.chars().nth(0).unwrap()) + ca.pad_start(length as usize, fill_char.chars().nth(0).unwrap()) .into_series(), )) }; @@ -667,7 +667,7 @@ impl JsExpr { let function = move |s: Series| { let ca = s.utf8()?; Ok(Some( - ca.ljust(length as usize, fill_char.chars().nth(0).unwrap()) + ca.pad_end(length as usize, fill_char.chars().nth(0).unwrap()) .into_series(), )) }; @@ -1048,15 +1048,15 @@ impl JsExpr { } #[napi(catch_unwind)] pub fn keep_name(&self) -> JsExpr { - self.inner.clone().keep_name().into() + self.inner.clone().name().keep().into() } #[napi(catch_unwind)] pub fn prefix(&self, prefix: String) -> JsExpr { - self.inner.clone().prefix(&prefix).into() + self.inner.clone().name().prefix(&prefix).into() } #[napi(catch_unwind)] pub fn suffix(&self, suffix: String) -> JsExpr { - self.inner.clone().suffix(&suffix).into() + self.inner.clone().name().suffix(&suffix).into() } #[napi(catch_unwind)] @@ -1224,8 +1224,8 @@ impl JsExpr { } #[napi(catch_unwind)] - pub fn list_shift(&self, periods: Wrap) -> JsExpr { - self.inner.clone().list().shift(periods.0).into() + pub fn list_shift(&self, periods: &JsExpr) -> JsExpr { + self.inner.clone().list().shift(periods.inner.clone()).into() } #[napi(catch_unwind)] pub fn list_slice(&self, offset: &JsExpr, length: Option<&JsExpr>) -> JsExpr { @@ -1248,6 +1248,14 @@ impl JsExpr { .into() } #[napi(catch_unwind)] + pub fn list_contains(&self, expr: &JsExpr) -> JsExpr { + self.inner + .clone() + .list() + .contains(expr.inner.clone()) + .into() + } + #[napi(catch_unwind)] pub fn rank(&self, method: Wrap, reverse: bool, seed: Option>) -> JsExpr { // Safety: // Wrap is transparent. @@ -1276,8 +1284,8 @@ impl JsExpr { self.inner.clone().kurtosis(fisher, bias).into() } #[napi(catch_unwind)] - pub fn str_concat(&self, delimiter: String) -> JsExpr { - self.inner.clone().str().concat(&delimiter).into() + pub fn str_concat(&self, delimiter: String, ignore_nulls: bool) -> JsExpr { + self.inner.clone().str().concat(&delimiter, ignore_nulls).into() } #[napi(catch_unwind)] pub fn cat_set_ordering(&self, ordering: String) -> JsExpr { @@ -1294,8 +1302,8 @@ impl JsExpr { self.inner.clone().reshape(&dims).into() } #[napi(catch_unwind)] - pub fn cumcount(&self, reverse: bool) -> JsExpr { - self.inner.clone().cumcount(reverse).into() + pub fn cum_count(&self, reverse: bool) -> JsExpr { + self.inner.clone().cum_count(reverse).into() } #[napi(catch_unwind)] pub fn to_physical(&self) -> JsExpr { @@ -1610,8 +1618,8 @@ pub fn spearman_rank_corr( } #[napi(catch_unwind)] -pub fn cov(a: Wrap, b: Wrap) -> JsExpr { - polars::lazy::dsl::cov(a.0, b.0).into() +pub fn cov(a: Wrap, b: Wrap, ddof: u8) -> JsExpr { + polars::lazy::dsl::cov(a.0, b.0, ddof).into() } #[napi(catch_unwind)] @@ -1654,27 +1662,42 @@ pub fn as_struct(exprs: Vec<&JsExpr>) -> JsExpr { #[napi(catch_unwind)] pub fn all_horizontal(exprs: Vec<&JsExpr>) -> JsExpr { let exprs = exprs.to_exprs(); - dsl::all_horizontal(exprs).into() + dsl::all_horizontal(exprs) + .map_err(JsPolarsErr::from) + .unwrap() + .into() } #[napi(catch_unwind)] pub fn any_horizontal(exprs: Vec<&JsExpr>) -> JsExpr { let exprs = exprs.to_exprs(); - dsl::any_horizontal(exprs).into() + dsl::any_horizontal(exprs) + .map_err(JsPolarsErr::from) + .unwrap() + .into() } #[napi(catch_unwind)] pub fn min_horizontal(exprs: Vec<&JsExpr>) -> JsExpr { let exprs = exprs.to_exprs(); - dsl::min_horizontal(exprs).into() + dsl::min_horizontal(exprs) + .map_err(JsPolarsErr::from) + .unwrap() + .into() } #[napi(catch_unwind)] pub fn max_horizontal(exprs: Vec<&JsExpr>) -> JsExpr { let exprs = exprs.to_exprs(); - dsl::max_horizontal(exprs).into() + dsl::max_horizontal(exprs) + .map_err(JsPolarsErr::from) + .unwrap() + .into() } #[napi(catch_unwind)] pub fn sum_horizontal(exprs: Vec<&JsExpr>) -> JsExpr { let exprs = exprs.to_exprs(); - dsl::sum_horizontal(exprs).into() + dsl::sum_horizontal(exprs) + .map_err(JsPolarsErr::from) + .unwrap() + .into() } diff --git a/src/series.rs b/src/series.rs index 9d293b8e1..13cfb7d0c 100644 --- a/src/series.rs +++ b/src/series.rs @@ -336,24 +336,24 @@ impl JsSeries { Ok(out.into()) } #[napi(catch_unwind)] - pub fn cumsum(&self, reverse: Option) -> napi::Result { + pub fn cum_sum(&self, reverse: Option) -> napi::Result { let reverse = reverse.unwrap_or(false); - Ok(cumsum(&self.series, reverse).map_err(JsPolarsErr::from)?.into()) + Ok(cum_sum(&self.series, reverse).map_err(JsPolarsErr::from)?.into()) } #[napi(catch_unwind)] - pub fn cummax(&self, reverse: Option) -> napi::Result { + pub fn cum_max(&self, reverse: Option) -> napi::Result { let reverse = reverse.unwrap_or(false); - Ok(cummax(&self.series, reverse).map_err(JsPolarsErr::from)?.into()) + Ok(cum_max(&self.series, reverse).map_err(JsPolarsErr::from)?.into()) } #[napi(catch_unwind)] - pub fn cummin(&self, reverse: Option) -> napi::Result { + pub fn cum_min(&self, reverse: Option) -> napi::Result { let reverse = reverse.unwrap_or(false); - Ok(cummin(&self.series, reverse).map_err(JsPolarsErr::from)?.into()) + Ok(cum_min(&self.series, reverse).map_err(JsPolarsErr::from)?.into()) } #[napi(catch_unwind)] - pub fn cumprod(&self, reverse: Option) -> napi::Result { + pub fn cum_prod(&self, reverse: Option) -> napi::Result { let reverse = reverse.unwrap_or(false); - Ok(cumprod(&self.series, reverse).map_err(JsPolarsErr::from)?.into()) + Ok(cum_prod(&self.series, reverse).map_err(JsPolarsErr::from)?.into()) } #[napi(catch_unwind)] pub fn chunk_lengths(&self) -> Vec { @@ -629,8 +629,8 @@ impl JsSeries { Ok(s.into()) } #[napi(catch_unwind)] - pub fn take_every(&self, n: i64) -> JsSeries { - let s = self.series.take_every(n as usize); + pub fn gather_every(&self, n: i64) -> JsSeries { + let s = self.series.gather_every(n as usize); s.into() } #[napi(catch_unwind)] @@ -950,7 +950,7 @@ impl JsSeries { pub fn str_pad_start(&self, length: i64, fill_char: String) -> napi::Result { let ca = self.series.utf8().map_err(JsPolarsErr::from)?; let s = ca - .rjust(length as usize, fill_char.chars().nth(0).unwrap()) + .pad_start(length as usize, fill_char.chars().nth(0).unwrap()) .into_series(); Ok(s.into()) } @@ -958,7 +958,7 @@ impl JsSeries { pub fn str_pad_end(&self, length: i64, fill_char: String) -> napi::Result { let ca = self.series.utf8().map_err(JsPolarsErr::from)?; let s = ca - .ljust(length as usize, fill_char.chars().nth(0).unwrap()) + .pad_end(length as usize, fill_char.chars().nth(0).unwrap()) .into_series(); Ok(s.into()) } @@ -1167,8 +1167,8 @@ impl JsSeries { #[napi(catch_unwind)] pub fn abs(&self) -> napi::Result { - let out = self.series.abs().map_err(JsPolarsErr::from)?; - Ok(out.into()) + let s = abs(&self.series).map_err(JsPolarsErr::from)?; + Ok(s.into()) } #[napi(catch_unwind)] diff --git a/yarn.lock b/yarn.lock index 25f55774e..c69260674 100644 --- a/yarn.lock +++ b/yarn.lock @@ -804,12 +804,12 @@ __metadata: languageName: node linkType: hard -"@napi-rs/cli@npm:^2.16.4": - version: 2.16.4 - resolution: "@napi-rs/cli@npm:2.16.4" +"@napi-rs/cli@npm:^2.16.5": + version: 2.16.5 + resolution: "@napi-rs/cli@npm:2.16.5" bin: napi: scripts/index.js - checksum: cc4eea0719c649ee9f9704a20bcd6a55dd48f5622edecc1ff47611f09c7ad0e45c865c4c5ebc11fa1c5166dea996bee39c0c2dac9edd9c2be7b1cc74940bb296 + checksum: 8d6583572638c8b9c7b6df440d4627958cc877e6b7bb5ebda58ae74b70aa3ce72b2054c8d6ecc7ba15a2710bb6f14a90f5ee75852fa234e1392760ecf36d4ae7 languageName: node linkType: hard @@ -930,10 +930,10 @@ __metadata: languageName: node linkType: hard -"@types/chance@npm:^1.1.5": - version: 1.1.5 - resolution: "@types/chance@npm:1.1.5" - checksum: fd27552c7c38ebf60a721f7b5af77de9808df6b5f5bf6ee784c6c2ec62edb730ac76c502d736fbc5c59c77baaef8e70e83279e80d7adee4263d420f6e847a185 +"@types/chance@npm:^1.1.6": + version: 1.1.6 + resolution: "@types/chance@npm:1.1.6" + checksum: a1845ff0a70989d581b8f7628aaef1807276c0ae22d0c038013ebcac4f4bd57e6a765319377994cc3cae2122838638fdb2afe5232ee6b987b3f7ea2cddecbead languageName: node linkType: hard @@ -971,13 +971,13 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:^29.5.7": - version: 29.5.7 - resolution: "@types/jest@npm:29.5.7" +"@types/jest@npm:^29.5.10": + version: 29.5.10 + resolution: "@types/jest@npm:29.5.10" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: e28624ccb0ef1255a03fbbb4b5bc3e5cbcdc450d39e0739985ff679b124198f808c38c8c3e67859c6efc0e848196deeb8cfed028e12a821c511dfc1112a2d6e9 + checksum: ef385905787db528de9b6beb2688865c0bb276e64256ed60b9a1a6ffc0b75737456cb5e27e952a3241c5845b6a1da487470010dd30f3ca59c8581624c564a823 languageName: node linkType: hard @@ -988,12 +988,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.8.10": - version: 20.8.10 - resolution: "@types/node@npm:20.8.10" +"@types/node@npm:^20.10.0": + version: 20.10.0 + resolution: "@types/node@npm:20.10.0" dependencies: undici-types: ~5.26.4 - checksum: 7c61190e43e8074a1b571e52ff14c880bc67a0447f2fe5ed0e1a023eb8a23d5f815658edb98890f7578afe0f090433c4a635c7c87311762544e20dd78723e515 + checksum: face395140d6f2f1755b91fdd3b697cf56aeb9e2514529ce88d56e56f261ad65be7269d863520a9406d73c338699ea68b418e8677584de0c1efeed09539b6f97 languageName: node linkType: hard @@ -1028,18 +1028,18 @@ __metadata: linkType: hard "acorn-walk@npm:^8.1.1": - version: 8.2.0 - resolution: "acorn-walk@npm:8.2.0" - checksum: 1715e76c01dd7b2d4ca472f9c58968516a4899378a63ad5b6c2d668bba8da21a71976c14ec5f5b75f887b6317c4ae0b897ab141c831d741dc76024d8745f1ad1 + version: 8.3.0 + resolution: "acorn-walk@npm:8.3.0" + checksum: 15ea56ab6529135be05e7d018f935ca80a572355dd3f6d3cd717e36df3346e0f635a93ae781b1c7942607693e2e5f3ef81af5c6fc697bbadcc377ebda7b7f5f6 languageName: node linkType: hard "acorn@npm:^8.4.1": - version: 8.10.0 - resolution: "acorn@npm:8.10.0" + version: 8.11.2 + resolution: "acorn@npm:8.11.2" bin: acorn: bin/acorn - checksum: 538ba38af0cc9e5ef983aee196c4b8b4d87c0c94532334fa7e065b2c8a1f85863467bb774231aae91613fcda5e68740c15d97b1967ae3394d20faddddd8af61d + checksum: 818450408684da89423e3daae24e4dc9b68692db8ab49ea4569c7c5abb7a3f23669438bf129cc81dfdada95e1c9b944ee1bfca2c57a05a4dc73834a612fbf6a7 languageName: node linkType: hard @@ -3068,17 +3068,17 @@ __metadata: resolution: "nodejs-polars@workspace:." dependencies: "@biomejs/biome": ^1.3.3 - "@napi-rs/cli": ^2.16.4 - "@types/chance": ^1.1.5 - "@types/jest": ^29.5.7 - "@types/node": ^20.8.10 + "@napi-rs/cli": ^2.16.5 + "@types/chance": ^1.1.6 + "@types/jest": ^29.5.10 + "@types/node": ^20.10.0 chance: ^1.1.11 jest: ^29.7.0 source-map-support: ^0.5.21 ts-jest: ^29.1.1 ts-node: ^10.9.1 typedoc: ^0.25.3 - typescript: 5.2.2 + typescript: 5.3.2 languageName: unknown linkType: soft @@ -3839,23 +3839,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.2.2": - version: 5.2.2 - resolution: "typescript@npm:5.2.2" +"typescript@npm:5.3.2": + version: 5.3.2 + resolution: "typescript@npm:5.3.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 7912821dac4d962d315c36800fe387cdc0a6298dba7ec171b350b4a6e988b51d7b8f051317786db1094bd7431d526b648aba7da8236607febb26cf5b871d2d3c + checksum: d92534dda639eb825db013203404c1fabca8ac630564283c9e7dc9e64fd9c9346c2de95ecebdf3e6e8c1c32941bca1cfe0da37877611feb9daf8feeaea58d230 languageName: node linkType: hard -"typescript@patch:typescript@5.2.2#~builtin": - version: 5.2.2 - resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=14eedb" +"typescript@patch:typescript@5.3.2#~builtin": + version: 5.3.2 + resolution: "typescript@patch:typescript@npm%3A5.3.2#~builtin::version=5.3.2&hash=14eedb" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 07106822b4305de3f22835cbba949a2b35451cad50888759b6818421290ff95d522b38ef7919e70fb381c5fe9c1c643d7dea22c8b31652a717ddbd57b7f4d554 + checksum: c034461079fbfde3cb584ddee52afccb15b6e32a0ce186d0b2719968786f7ca73e1b07f71fac4163088790b16811c6ccf79680de190664ef66ff0ba9c1fe4a23 languageName: node linkType: hard