Polars:最强 Pandas 平替?

比起 Pandas, 你更需要 Polars:详细指南 在数据分析领域,Python 由于其多功能性和广泛的库生态系统而成为一种流行的语言。数据处理和分析在提取见解和做出明智决策方面发挥着至关重要的作用。然而,随着数据集的规模和复杂性不断增长,对高性能解决方案的需求变得至关重要。有效地处理大型数据集需要能够提供快速计算和优化操作的工具。这就是 Polars 出现的原因。Polars 是一个强大的开源库,专为 Python 中的高性能数据操作和分析而设计。 阅读详情

你好,我是坚持分享干货的 EarlGrey,翻译出版过《Python编程无师自通》、《Python并行计算手册》等技术书籍。

如果我的分享对你有帮助,请关注我,一起向上进击。

创作不易,希望大家给一点鼓励,把公众号设置为“星标”,给文章点个“赞”和“在看”,谢谢大家啦~

Pandas 是久负盛名的 Python 数据处理库,试图挑战它的后来者非常多。之前我们介绍过 CuDF,今天我们再分享一个高性能的DataFrame库,Polars。本文分享自数据studio,希望大家喜欢。

Polars是一个用于操作结构化数据的高性能DataFrame库,可以说是平替pandas最有潜质的包。当然pandas目前作为Python数据分析的核心工具来说还是最强的。

Polars其核心部分是用Rust编写的,但该库也提供了Python接口。它的主要特点包括:

  • 快速: Polars是从零开始编写的,紧密与机器结合,没有外部依赖。

  • I/O: 对所有常见数据存储层提供一流支持:本地、云存储和数据库。

  • 易于使用: 以原始意图编写查询。Polars 在内部会使用其查询优化器确定执行最有效的方式。

  • 离线处理: Polars支持通过其流式API进行离线数据转换。这使您能够处理结果,而无需同时将所有数据存储在内存中。

  • 并行处理: Polars通过在可用的CPU核心之间分配工作负载,充分利用计算机性能,而无需额外配置。

  • 矢量化查询引擎: Polars使用 Apache Arrow,一种列式数据格式,以矢量化方式处理查询。它使用 SIMD 来优化CPU使用。

User guide: https://pola-rs.github.io/polars/user-guide/
API reference: https://pola-rs.github.io/polars/py-polars/html/reference/io.html

介绍

Polars 的目标是提供一个闪电般快速的 DataFrame 库,具有以下特点:

  • 利用计算机上所有可用的核心。

  • 通过优化查询来减少不必要的工作/内存分配。

  • 处理比可用 RAM 更大得多的数据集。

  • 具有一致且可预测的 API。

  • 具有严格的模式(在运行查询之前应该知道数据类型)。

Polars 是用 Rust 编写的,这使得它具有 C/C++ 性能,并允许它完全控制查询引擎中的性能关键部分。因此,Polars 为此付出了很大的努力:

  • 减少冗余的复制。

  • 高效地遍历内存缓存。

  • 在并行性中最小化争用。

  • 以块处理数据。

  • 重用内存分配。

基础

Series & DataFrames

Series 是一个一维数据结构。在一个 Series 中,所有元素都具有相同的数据类型(例如,整数、字符串)。下面的片段展示了如何创建一个简单的带有名称的 Series 对象。

import polars as pl
import numpy as np

s = pl.Series("a", [1, 2, 3, 4, 5])
print(s)
s = pl.Series("a", [1, 2, 3, 4, 5])
print(s.min())
print(s.max())
s = pl.Series("a", ["polar", "bear", "arctic", "polar fox", "polar bear"])
s2 = s.str.replace("polar", "pola")
print(s2)
from datetime import date

start = date(2001, 1, 1)
stop = date(2001, 1, 9)
s = pl.date_range(start, stop, interval="2d", eager=True)
print(s.dt.day())

DataFrame 是一个二维数据结构,由一个或多个 Series 支持,可以看作是对一系列(例如列表)Series的抽象。在 DataFrame 上可以执行的操作与在 SQL 查询中执行的操作非常相似。您可以进行 GROUP BY、JOIN、PIVOT,还可以定义自定义函数。

from datetime import datetime

df = pl.DataFrame(
    {
        "integer": [1, 2, 3, 4, 5],
        "date": [
            datetime(2022, 1, 1),
            datetime(2022, 1, 2),
            datetime(2022, 1, 3),
            datetime(2022, 1, 4),
            datetime(2022, 1, 5),
        ],
        "float": [4.0, 5.0, 6.0, 7.0, 8.0],
    }
)

print(df)
print(df.head(3))
print(df.describe())

Reading & writing

import polars as pl
from datetime import datetime

df = pl.DataFrame(
    {
        "integer": [1, 2, 3],
        "date": [
            datetime(2022, 1, 1),
            datetime(2022, 1, 2),
            datetime(2022, 1, 3),
        ],
        "float": [4.0, 5.0, 6.0],
    }
)

print(df)
df.write_csv("output.csv")
df_csv = pl.read_csv("output.csv")
print(df_csv)
df_csv = pl.read_csv("output.csv", try_parse_dates=True)
print(df_csv)

Expressions

import polars as pl

# 创建一个简单的 DataFrame
data = {'column1': [1, 2, 3],
        'column2': ['a', 'b', 'c']}
df = pl.DataFrame(data)

# 使用表达式进行选择
selected_df = df.select(['column1'])

# 使用表达式进行过滤
filtered_df = df.filter(df['column1'] > 1)
selected_df
filtered_df

拼接

df = pl.DataFrame(
    {
        "a": np.arange(0, 8),
        "b": np.random.rand(8),
        "d": [1, 2.0, np.NaN, np.NaN, 0, -5, -42, None],
    }
)

df2 = pl.DataFrame(
    {
        "x": np.arange(0, 8),
        "y": ["A", "A", "A", "B", "B", "C", "X", "X"],
    }
)
joined = df.join(df2, left_on="a", right_on="x")
print(joined)
stacked = df.hstack(df2)
print(stacked)

概念

Data types

Polars 完全基于 Arrow 数据类型,并由 Arrow 内存数组支持。这使得数据处理在缓存效率和跨进程通信方面得到良好支持。大多数数据类型都与 Arrow 的实现完全一致,但有一些例外,如 Utf8(实际上是 LargeUtf8)、Categorical 和 Object(支持有限)等。以下是一些数据类型:

分组类型详细信息
数值Int88 位有符号整数。

Int1616 位有符号整数。

Int3232 位有符号整数。

Int6464 位有符号整数。

UInt88 位无符号整数。

UInt1616 位无符号整数。

UInt3232 位无符号整数。

UInt6464 位无符号整数。

Float3232 位浮点数。

Float6464 位浮点数。
嵌套Struct结构数组表示为 Vec<Series>,用于在单个列中打包多个/异构值。

List列表数组包含包含列表值的子数组和一个偏移数组(在内部实际上是 Arrow 的 LargeList)。
时间Date日期表示,内部表示为距离 UNIX 纪元的天数,由 32 位有符号整数编码。

Datetime日期时间表示,内部表示为距离 UNIX 纪元的微秒数,由 64 位有符号整数编码。

Duration表示时间差的类型,内部表示为微秒。通过减去 Date/Datetime 创建。

Time时间表示,内部表示为距午夜的纳秒数。
其他Boolean布尔类型,实际上是按位打包的。

Utf8字符串数据(实际上在内部是 Arrow 的 LargeUtf8)。

Binary以字节形式存储数据。

Object有限支持的数据类型,可以是任何值。

Categorical一组字符串的分类编码。

Contexts

Polars 已经开发了自己的领域特定语言(DSL)用于数据转换。该语言非常易于使用,允许进行复杂的查询,同时保持人类可读性。该语言的两个核心组件是上下文(Contexts)和表达式(Expressions),我们将在下一部分介绍表达式。

正如名称所示,上下文指的是需要评估表达式的上下文。有三个主要的上下文 [^1^]:

  1. 选择(Selection): df.select([..]), df.with_columns([..])

  2. 过滤(Filtering): df.filter()

  3. 分组/聚合(Group by / Aggregation): df.group_by(..).agg([..])

df = pl.DataFrame(
    {
        "nrs": [1, 2, 3, None, 5],
        "names": ["foo", "ham", "spam", "egg", None],
        "random": np.random.rand(5),
        "groups": ["A", "A", "B", "C", "B"],
    }
)
print(df)
# 基于df 进行计算,得到新的表格
out = df.select(
    pl.sum("nrs"), # nrs的和
    pl.col("names").sort(), # names排序后的结果
    pl.col("names").first().alias("first name"), # names第一个值
    (pl.mean("nrs") * 10).alias("10xnrs"), # nrs的均值 * 10
)
print(out)
# 原始df 新增列
df = df.with_columns(
    pl.sum("nrs").alias("nrs_sum"),
    pl.col("random").count().alias("count"),
)
print(df)
out = df.filter(pl.col("nrs") > 2)
print(out)
out = df.group_by("groups").agg(
    pl.sum("nrs"),  # sum nrs by groups
    pl.col("random").count().alias("count"),  # count group members
    # sum random where name != null
    pl.col("random").filter(pl.col("names").is_not_null()).sum().name.suffix("_sum"),
    pl.col("names").reverse().alias("reversed names"),
)
print(out)

Lazy / eager API

Polars支持两种操作模式:lazy(延迟)和eager(即时)。在eager API中,查询会立即执行,而在lazy API中,查询只有在“需要”时才会被评估。

!wget https://mirror.coggle.club/dataset/heart.csv
!head heart.csv
df = pl.read_csv("heart.csv")
df_small = df.filter(pl.col("age") > 5)
df_agg = df_small.group_by("sex").agg(pl.col("chol").mean())
print(df_agg)
q = (
    pl.scan_csv("heart.csv")
    .filter(pl.col("age") > 5)
    .group_by("sex")
    .agg(pl.col("chol").mean())
)
# 生成了计算逻辑

df = q.collect() # 真正计算
print(df)

Streaming API

https://pola-rs.github.io/polars/user-guide/concepts/streaming/

Lazy API的另一个额外好处是它允许以流式方式执行查询。与一次性处理所有数据不同,Polars可以按批执行查询,使您能够处理大于内存的数据集。

q = (
    pl.scan_csv("heart.csv")
    .filter(pl.col("age") > 5)
    .group_by("sex")
    .agg(pl.col("chol").mean())
)

df = q.collect(streaming=True)
print(df)

表达式

Basic operators

df = pl.DataFrame(
    {
        "nrs": [1, 2, 3, None, 5],
        "names": ["foo", "ham", "spam", "egg", None],
        "random": np.random.rand(5),
        "groups": ["A", "A", "B", "C", "B"],
    }
)
print(df)
df_numerical = df.select(
    (pl.col("nrs") + 5).alias("nrs + 5"),
    (pl.col("nrs") - 5).alias("nrs - 5"),
    (pl.col("nrs") * pl.col("random")).alias("nrs * random"),
    (pl.col("nrs") / pl.col("random")).alias("nrs / random"),
)
print(df_numerical)
df_logical = df.select(
    (pl.col("nrs") > 1).alias("nrs > 1"),
    (pl.col("random") <= 0.5).alias("random <= .5"),
    (pl.col("nrs") != 1).alias("nrs != 1"),
    (pl.col("nrs") == 1).alias("nrs == 1"),
    ((pl.col("random") <= 0.5) & (pl.col("nrs") > 1)).alias("and_expr"),  # and
    ((pl.col("random") <= 0.5) | (pl.col("nrs") > 1)).alias("or_expr"),  # or
)
print(df_logical)

Column selections

from datetime import date, datetime

df = pl.DataFrame(
    {
        "id": [9, 4, 2],
        "place": ["Mars", "Earth", "Saturn"],
        "date": pl.date_range(date(2022, 1, 1), date(2022, 1, 3), "1d", eager=True),
        "sales": [33.4, 2142134.1, 44.7],
        "has_people": [False, True, False],
        "logged_at": pl.datetime_range(
            datetime(2022, 12, 1), datetime(2022, 12, 1, 0, 0, 2), "1s", eager=True
        ),
    }
).with_row_count("rn")
print(df)
out = df.select(pl.col("*"))

# Is equivalent to
out = df.select(pl.all())
print(out)
out = df.select(pl.col("*").exclude("logged_at", "rn"))
print(out)
out = df.select(pl.col("date", "logged_at").dt.to_string("%Y-%h-%d"))
print(out)
out = df.select(pl.col("^.*(as|sa).*$"))
print(out)
out = df.select(pl.col(pl.Int64, pl.UInt32, pl.Boolean).n_unique())
print(out)
import polars.selectors as cs
out = df.select(cs.numeric() - cs.first())
print(out)
out = df.select(cs.contains("rn"), cs.matches(".*_.*"))
print(out)

Functions

df = pl.DataFrame(
    {
        "nrs": [1, 2, 3, None, 5],
        "names": ["foo", "ham", "spam", "egg", "spam"],
        "random": np.random.rand(5),
        "groups": ["A", "A", "B", "C", "B"],
    }
)
print(df)
df_samename = df.select(pl.col("nrs") + 5)
print(df_samename)
df_alias = df.select(
    (pl.col("nrs") + 5).alias("nrs + 5"),
    (pl.col("nrs") - 5).alias("nrs - 5"),
)
print(df_alias)
df_alias = df.select(
    pl.col("names").n_unique().alias("unique"),
    pl.approx_n_unique("names").alias("unique_approx"),
)
print(df_alias)
df_conditional = df.select(
    pl.col("nrs"),
    pl.when(pl.col("nrs") > 2)
    .then(pl.lit(True))
    .otherwise(pl.lit(False))
    .alias("conditional"),
)
print(df_conditional)

转换

类型转换(Casting)将列的底层 DataType 转换为新的数据类型。Polars 使用 Arrow 在内存中管理数据,并依赖于 Rust 实现中的计算核心 来执行转换。类型转换通过 cast() 方法实现。

cast 方法包括一个 strict 参数,该参数确定当 Polars 遇到无法从源 DataType 转换为目标 DataType 的值时的行为。默认情况下,strict=True,这意味着 Polars 将引发错误,通知用户转换失败,并提供无法转换的值的详细信息。另一方面,如果 strict=False,无法转换为目标 DataType 的任何值都将悄悄地转换为 null。

df = pl.DataFrame(
    {
        "integers": [1, 2, 3, 4, 5],
        "big_integers": [1, 10000002, 3, 10000004, 10000005],
        "floats": [4.0, 5.0, 6.0, 7.0, 8.0],
        "floats_with_decimal": [4.532, 5.5, 6.5, 7.5, 8.5],
    }
)

print(df)
out = df.select(
    pl.col("integers").cast(pl.Float32).alias("integers_as_floats"),
    pl.col("floats").cast(pl.Int32).alias("floats_as_integers"),
    pl.col("floats_with_decimal")
    .cast(pl.Int32)
    .alias("floats_with_decimal_as_integers"),
)
print(out)
out = df.select(
    pl.col("integers").cast(pl.Int16).alias("integers_smallfootprint"),
    pl.col("floats").cast(pl.Float32).alias("floats_smallfootprint"),
)
print(out)
df = pl.DataFrame(
    {
        "integers": [1, 2, 3, 4, 5],
        "float": [4.0, 5.03, 6.0, 7.0, 8.0],
        "floats_as_string": ["4.0", "5.0", "6.0", "7.0", "8.0"],
    }
)

out = df.select(
    pl.col("integers").cast(pl.Utf8),
    pl.col("float").cast(pl.Utf8),
    pl.col("floats_as_string").cast(pl.Float64),
)
print(out)
df = pl.DataFrame(
    {
        "integers": [-1, 0, 2, 3, 4],
        "floats": [0.0, 1.0, 2.0, 3.0, 4.0],
        "bools": [True, False, True, False, True],
    }
)

out = df.select(pl.col("integers").cast(pl.Boolean), pl.col("floats").cast(pl.Boolean))
print(out)
from datetime import date, datetime

df = pl.DataFrame(
    {
        "date": pl.date_range(date(2022, 1, 1), date(2022, 1, 5), eager=True),
        "datetime": pl.datetime_range(
            datetime(2022, 1, 1), datetime(2022, 1, 5), eager=True
        ),
    }
)

out = df.select(pl.col("date").cast(pl.Int64), pl.col("datetime").cast(pl.Int64))
print(out)

Strings

df = pl.DataFrame({"animal": ["Crab", "cat and dog", "rab$bit", None]})

out = df.select(
    pl.col("animal").str.len_bytes().alias("byte_count"),
    pl.col("animal").str.len_chars().alias("letter_count"),
)
print(out)
out = df.select(
    pl.col("animal"),
    pl.col("animal").str.contains("cat|bit").alias("regex"),
    pl.col("animal").str.contains("rab$", literal=True).alias("literal"),
    pl.col("animal").str.starts_with("rab").alias("starts_with"),
    pl.col("animal").str.ends_with("dog").alias("ends_with"),
)
print(out)

Aggregation

https://pola-rs.github.io/polars/user-guide/expressions/aggregation/

df = pl.read_csv("heart.csv")
print(df)
q = (
    df.lazy()
    .group_by("sex")
    .agg(
        pl.count(),
        pl.col("cp"),
        pl.first("caa"),
    )
    .sort("count", descending=True)
    .limit(5)
)

df = q.collect()
print(df)
q = (
    df.lazy()
    .group_by("sex")
    .agg(
        (pl.col("cp") == 1).sum().alias("anti"),
        (pl.col("cp") == 2).sum().alias("pro"),
    )
    .sort("pro", descending=True)
    .limit(5)
)

df = q.collect()
print(df)

缺失值

df = pl.DataFrame(
    {
        "value": [1, None],
    },
)
print(df)
null_count_df = df.null_count()
print(null_count_df)
df = pl.DataFrame(
    {
        "col1": [1, 2, 3],
        "col2": [1, None, 3],
    },
)
print(df)
fill_literal_df = df.with_columns(
    pl.col("col2").fill_null(pl.lit(2)),
)
print(fill_literal_df)
fill_forward_df = df.with_columns(
    pl.col("col2").fill_null(strategy="forward"),
)
print(fill_forward_df)
fill_median_df = df.with_columns(
    pl.col("col2").fill_null(pl.median("col2")),
)
print(fill_median_df)
fill_interpolation_df = df.with_columns(
    pl.col("col2").interpolate(),
)
print(fill_interpolation_df)

Window functions

https://pola-rs.github.io/polars/user-guide/expressions/window/

!wget https://cdn.coggle.club/Pokemon.csv
!head Pokemon.csv
# then let's load some csv data with information about pokemon
df = pl.read_csv("Pokemon.csv")
print(df.head())
out = df.select(
    "Type 1",
    "Type 2",
    pl.col("Attack").mean().over("Type 1").alias("avg_attack_by_type"),
    pl.col("Defense")
    .mean()
    .over(["Type 1", "Type 2"])
    .alias("avg_defense_by_type_combination"),
    pl.col("Attack").mean().alias("avg_attack"),
)
print(out)
filtered = df.filter(pl.col("Type 2") == "Psychic").select(
    "Name",
    "Type 1",
    "Speed",
)
print(filtered)
out = filtered.with_columns(
    pl.col(["Name", "Speed"]).sort_by("Speed", descending=True).over("Type 1"),
)
print(out)

Lists and Arrays

weather = pl.DataFrame(
    {
        "station": ["Station " + str(x) for x in range(1, 6)],
        "temperatures": [
            "20 5 5 E1 7 13 19 9 6 20",
            "18 8 16 11 23 E2 8 E2 E2 E2 90 70 40",
            "19 24 E9 16 6 12 10 22",
            "E2 E0 15 7 8 10 E1 24 17 13 6",
            "14 8 E0 16 22 24 E1",
        ],
    }
)
print(weather)
out = weather.with_columns(pl.col("temperatures").str.split(" "))
print(out)
out = weather.with_columns(pl.col("temperatures").str.split(" ")).explode(
    "temperatures"
)
print(out)
out = weather.with_columns(pl.col("temperatures").str.split(" ")).with_columns(
    pl.col("temperatures").list.head(3).alias("top3"),
    pl.col("temperatures").list.slice(-3, 3).alias("bottom_3"),
    pl.col("temperatures").list.len().alias("obs"),
)
print(out)

变形

Joins

策略描述
inner返回两个数据框中具有匹配键的行。左框或右框中的非匹配行将被丢弃。
left返回左数据框中的所有行,无论是否在右数据框中找到匹配项。非匹配行的右列将被填充为null。
outer返回左右两个数据框中的所有行。如果在一个框中找不到匹配项,则从另一个框中的列将被填充为null。
cross返回左框中的所有行与右框中的所有行的笛卡尔积。重复的行将被保留;左框与右框的交叉连接的表长度始终为len(A) × len(B)。
asof在此连接中,匹配是根据最近的键而不是相等的键执行的左连接。
semi返回左框中具有与右框中相同的连接键的所有行。
anti返回左框中连接键不在右框中出现的所有行。
df_customers = pl.DataFrame(
    {
        "customer_id": [1, 2, 3],
        "name": ["Alice", "Bob", "Charlie"],
    }
)
print(df_customers)
df_orders = pl.DataFrame(
    {
        "order_id": ["a", "b", "c"],
        "customer_id": [1, 2, 2],
        "amount": [100, 200, 300],
    }
)
print(df_orders)
df = df_customers.join(df_orders, on="customer_id", how="inner")
print(df)

df = df_customers.join(df_orders, on="customer_id", how="left")
print(df)

df = df_customers.join(df_orders, on="customer_id", how="outer")
print(df)

df = df_customers.join(df_orders, on="customer_id", how="cross")
print(df)
df_cars = pl.DataFrame(
    {
        "id": ["a", "b", "c"],
        "make": ["ford", "toyota", "bmw"],
    }
)
print(df_cars)
df_repairs = pl.DataFrame(
    {
        "id": ["c", "c"],
        "cost": [100, 200],
    }
)
print(df_repairs)
df = df_cars.join(df_repairs, on="id", how="inner")
print(df)

df = df_cars.join(df_repairs, on="id", how="semi")
print(df)

df = df_cars.join(df_repairs, on="id", how="anti")
print(df)
df_trades = pl.DataFrame(
    {
        "time": [
            datetime(2020, 1, 1, 9, 1, 0),
            datetime(2020, 1, 1, 9, 1, 0),
            datetime(2020, 1, 1, 9, 3, 0),
            datetime(2020, 1, 1, 9, 6, 0),
        ],
        "stock": ["A", "B", "B", "C"],
        "trade": [101, 299, 301, 500],
    }
)
print(df_trades)

df_quotes = pl.DataFrame(
    {
        "time": [
            datetime(2020, 1, 1, 9, 0, 0),
            datetime(2020, 1, 1, 9, 2, 0),
            datetime(2020, 1, 1, 9, 4, 0),
            datetime(2020, 1, 1, 9, 6, 0),
        ],
        "stock": ["A", "B", "C", "A"],
        "quote": [100, 300, 501, 102],
    }
)

print(df_quotes)
df_asof_join = df_trades.join_asof(df_quotes, on="time", by="stock")
print(df_asof_join)
df_asof_tolerance_join = df_trades.join_asof(
    df_quotes, on="time", by="stock", tolerance="1m"
)
print(df_asof_tolerance_join)

Concatenation

df_v1 = pl.DataFrame(
    {
        "a": [1],
        "b": [3],
    }
)
df_v2 = pl.DataFrame(
    {
        "a": [2],
        "b": [4],
    }
)
df_vertical_concat = pl.concat(
    [
        df_v1,
        df_v2,
    ],
    how="vertical",
)
print(df_vertical_concat)
df_h1 = pl.DataFrame(
    {
        "l1": [1, 2],
        "l2": [3, 4],
    }
)
df_h2 = pl.DataFrame(
    {
        "r1": [5, 6],
        "r2": [7, 8],
        "r3": [9, 10],
    }
)
df_horizontal_concat = pl.concat(
    [
        df_h1,
        df_h2,
    ],
    how="horizontal",
)
print(df_horizontal_concat)

Pivots

df = pl.DataFrame(
    {
        "foo": ["A", "A", "B", "B", "C"],
        "N": [1, 2, 2, 4, 2],
        "bar": ["k", "l", "m", "n", "o"],
    }
)
print(df)
out = df.pivot(index="foo", columns="bar", values="N", aggregate_function="first")
print(out)
q = (
    df.lazy()
    .collect()
    .pivot(index="foo", columns="bar", values="N", aggregate_function="first")
    .lazy()
)
out = q.collect()
print(out)

Melts

import polars as pl

df = pl.DataFrame(
    {
        "A": ["a", "b", "a"],
        "B": [1, 3, 5],
        "C": [10, 11, 12],
        "D": [2, 4, 6],
    }
)
print(df)
out = df.melt(id_vars=["A", "B"], value_vars=["C", "D"])
print(out)

- EOF -

文章已经看到这了,别忘了在右下角点个“赞”和“在看”鼓励哦~

推荐阅读  点击标题可跳转

1、VS Code 变身小霸王游戏机!

2、认知升级:模型与范式转换

3、超赞的 Python 编译器,单核提速100倍

4、高效的终极秘诀

5、Python 3.12 版本有什么变化?

回复下方「关键词」,获取优质资源

回复关键词「 pybook03」,领取进击的Grey与小伙伴一起翻译的《Think Python 2e》电子版

回复关键词「书单02」,领取进击的Grey整理的 10 本 Python 入门书的电子版

👇关注我的公众号👇

告诉你更多细节干货

769b6316f788a898fbbf6a274f6ca6e4.jpeg

欢迎围观我的朋友圈

👆每天更新所想所悟

Polars使用指南(二) 快速学习polars的高级用法 阅读详情

相关推荐

基于中文在线文档的Polars工具介绍

Polars是一个能够提取(Extract)、转换(Transform)与加载(Load)大规模数据集的工具(快速多线程、单指令多数据流、延迟/即时执行、查询优化、混合流等)。根据官方开发人员的Benchmark结果,Polars版本号为0.8.8时,能够在143s左右导入维度在1,000,000,000*9左右,内存为50GB的数据集。与此同时,Pandas在1.2.2版本导入同样的数据集会出现out of memory的报错。

林景的博客 3358

又一款数据分析神器:Polars 真的很强大

相信对于不少的数据分析从业者来说呢,用的比较多的是Pandas以及SQL这两种工具,Pandas不但能够对数据集进行清理与分析,并且还能够绘制各种各样的炫酷的图表,但是遇到数据集很大的时候要是还使用Pandas来处理显然有点力不从心。 今天我就来介绍另外一个数据处理与分析工具,叫做Polars,它在数据处理的速度上更快,当然里面还包括两种API,一种是Eager API,另一种则是Lazy API,其中Eager API和Pandas的使用类似,语法类似差不太多,立即执行就能产生结果。喜欢本文记得收藏、关注

Python数据挖掘 7416

单机大数据处理新范式:Polars/DuckDB/Vaex/Modin选型指南

单机大数据处理正从Pandas时代迈向多引擎协同新阶段。其核心原理在于突破Python GIL限制、采用列式内存布局(如Arrow)、支持延迟计算与查询优化,从而实现CPU多核并行、IO高效利用和内存可控。这类工具的技术价值在于让GB至TB级数据在普通工作站上完成秒级交互分析,支撑实时特征工程、快速报表生成与探索式数据分析等关键场景。本文聚焦Polars、DuckDB、Vaex和Modin四大主流替代方案,结合真实业务负载对比其在读取、过滤、聚合、连接等典型操作中的性能表现与适用边界。

clijovtbq401783153的博客 366

超越Pandas:数据处理利器Polars的快速入门指南

Polars是一个用于数据处理和分析的快速、内存高效的Rust语言编写的数据操作库。它提供了类似于Pandas的API,但具有更好的性能和内存使用效率。本文将介绍Polars库的基本使用说明,并通过具体的代码案例展示其功能和特性。

WHYbeHERE的博客 3382

pandas性能瓶颈与五大替代方案基准测试

pandas作为Python数据分析基石,其易用性在大规模数据处理场景下常伴随内存效率低、计算延迟高等固有局限。理解列式计算、零拷贝内存模型和向量化执行原理,是突破单机DataFrame性能天花板的关键技术路径。这类优化不仅提升I/O吞吐与CPU缓存利用率,更直接支撑金融回测、实时风控、电商用户行为分析等高负载生产场景。本文基于5000万行以上真实业务数据,在统一硬件与严苛测试条件下,对polars、modin、vaex、dask.dataframe及arrow(pyarrow.compute)展开多维性能

weixin_30755393的博客 431

2022年被低估的AI工程化工具链:Polars/DVC/Evidently实战指南

在人工智能落地过程中,模型算法只是冰山一角,真正决定项目成败的是支撑AI从实验到生产的工程化能力。数据准备效率、实验可复现性、线上监控告警、数据质量治理——这些底层能力构成AI系统的‘隐形骨架’。本文聚焦于近年快速崛起的轻量级高生产力工具,如基于Rust的高性能DataFrame库Polars,实现Git式数据与模型版本管理的DVC,以及将统计漂移转化为业务可读报告的Evidently AI。它们不替代Pandas或Scikit-learn,而是补足其在规模化、协作化与可观测性上的短板,显著降低胶水代码占比

转些好文章,促进分享。 368

最强 Pandas 平替工具库:Polars

Polars 的目标是提供一个闪电般快速的。

Python数据挖掘 1871

NumPy+Pandas+Matplotlib数据可视化底层原理与实战

数据可视化不仅是图表生成,更是从原始数据到业务洞察的系统性工程。其核心依赖于NumPy的内存连续性与向量化计算、Pandas的结构化数据建模能力以及Matplotlib面向对象的视觉控制机制。理解这三者协同工作的底层原理——如NumPy dtype对内存与性能的影响、Pandas Series/DataFrame如何承载数据语义、Matplotlib Axes如何实现像素级渲染——是构建可复现、可维护、可交付图表的前提。该技术栈在资源受限环境(如2GB内存服务器)、Kaggle竞赛、教学演示及决策支持报告中

514

萝卜大杂烩 | Polars ,最强Pandas平替(内含实操代码,建议收藏!)

Polars是一个用于操作结构化数据的高性能DataFrame库,可以说是平替pandas最有潜质的包。当然pandas目前作为Python数据分析的核心工具来说还是最强的,完全值得我们深入学习。Polars其核心部分是用Rust编写的,但该库也提供了Python接口。

csdn_xmj的博客 4140

Pure Persuit算法基础

Pure Persuit算法本身的原理不难理解,它主要基于几何原理进行的设备控制,本身不考虑太多的运动学约束。同时机器人的路径跟踪效果应该会比较依赖于预瞄点。对于曲线部分而言,如果曲率很小而预瞄点很远的话,对于曲线的跟随性应该会很差。对于直线而言,如果设备在开始时与轨迹有横向偏差,则在运动过程中机器人会逐渐收敛到曲线,但是收敛速度取决于预瞄点距离。

YiYeZhiNian的博客 1522

别再傻傻分不清了!用Design Compiler和PrimeTime实操对比PBA与GBA模式

本文深度解析静态时序分析(STA)中Design Compiler与PrimeTime工具的PBA与GBA模式差异,通过实际案例演示两种模式在转换时间计算、时钟路径分析等方面的对比,并提供工程实践中模式选择的策略与调试技巧,帮助工程师在芯片设计流程中平衡精度与效率。

weixin_42552315的博客 415

最强 Pandas 平替 -- Polars

这是「进击的Coder」的第 912篇技术分享来源:Python 编程时光“ 阅读本文大概需要 9 分钟。 ”Polars 是一个用于操作结构化数据的高性能 DataFrame 库,可以说是平替 pandas 最有潜质的包。Polars 其核心部分是用 Rust 编写的,但该库也提供了 Python 接口。它的主要特点包括:快速: Polars 是从零开始编写的,紧密与机器结合,没有外部依赖。I...

静觅 538

RealSense D455启动教程

RealSense D455启动教程 修改rs_camera.launch

每天进步一点点 2418

Polars ,最强Pandas平替?

转自:数据studio大家好,我是阿粥~今天给大家分享关于Polars库的内容,前排提示,文末送两本好书~Polars是一个用于操作结构化数据的高性能DataFrame库,可以说是平替pandas最有潜质的包。Polars其核心部分是用Rust编写的,但该库也提供了Python接口。它的主要特点包括:快速: Polars是从零开始编写的,紧密与机器结合,没有外部依赖。I/O: 对所有常见数据存储层...

SeizeeveryDay的博客 586

LinuxCNC 源码解析:从界面开发到硬件交互的实战指南

本文深入解析LinuxCNC源码架构,从用户界面开发到硬件交互的实战指南。涵盖GTK与Tkinter界面开发、HAL硬件抽象层、G代码解析器改造及运动控制核心等关键模块,提供定制化开发技巧与性能优化方案,助力开发者高效掌握数控系统开发。

weixin_27066963的博客 190

DeepSeek赋能公文写作:从高效成文到精准传情的全维度指南

摘要:AI赋能公文写作的精准化实践 公文写作长期面临框架混乱、素材匮乏、表达不规范、修改低效等痛点。DeepSeek等AI工具通过"精准指令+分步赋能"模式实现突破:首先明确公文的目的性、逻辑性和规范性特征;其次采用包含场景、类型、目的等要素的指令模板;再分四步实施:框架搭建确保层次分明,内容填充解决素材问题,表达优化适配不同语体,合规校验把关格式规范。典型案例显示,AI能将数据罗列转化为"数据+成果+价值"的生动表述,使公文既规范又具感染力。这种AI赋能的写作方法显

通俗易懂学IT 233

【Python基础】最强 Pandas 平替 -- Polars

Polars 是一个用于操作结构化数据的高性能 DataFrame 库,可以说是平替 pandas 最有潜质的包。Polars 其核心部分是用 Rust 编写的,但该库也提供了 Python 接口。

dsuiofh的博客 1932

Vue3 - 实现集成配置百度语音识别转文字,长按或开启录音并将录音文件实时转换为文字,上传音频文件利用百度语音识别API转换为文本并展示(vue3百度智能云API实现上传录音文件并转换成文字案例)

vue3对接百度智能云语音识别,vue3 h5移动端网页中实现语音识别,百度语音识别录音转文字_百度智能云,vue3如何使用百度语音识别,如何将语音转文字,使用vue3实现录音并将录音转换为文字,vue3如何实现语音输入功能功能,vue3集成百度智能云API实现录音转文字详细教程完整示例代码demo,VUE3使用百度语音识别语音转文字,vue调用百度语音识别,vue3百度语音识别文字并展示功能,vue3免费语音转文本api,百度语音识别申请配置教程,Vue3项目配置自定义界面百度语音识别转文字和原生使用方式

🏆 前端领域优质创作者 2728

突破大数据处理瓶颈:Awesome Data Analysis收录20个高性能工具,Polars、Dask一网打尽

数据量从 GB 涨到 TB,Pandas 运行时间从秒级变成小时级——这是很多数据分析师的噩梦。开源项目 **Awesome Data Analysis** 是一个精心整理的**数据分析与数据科学资源合集**,涵盖 500+ 项资源:Python、SQL、统计学、机器学习、AI、可视化、速查表和面试准备。其中收录的 **Polars、Dask 等 20 个高性能大数据处理工具**,能让新手零门槛突

gitblog_00599的博客 544

Serdes之什么是(CDR)?

光收发器和电收发器使用的是我们所说的串行数据通信。在这种通信方式中,数据位是按顺序一个接一个地传输的。光收发器和电收发器使用的是我们所说的串行数据通信。在这种通信方式中,数据位是按顺序一个接一个地传输的。目前市场上大多数收发器都没有专用的时钟输入,因此时钟恢复和数据重新定时等功能是在收发器外部(即在主板上)进行的。接收端则需要恢复时钟以采样串行线上的数据。为了实现这一点,接收端需要一个与输入数据频率大致相同的时钟。通过使参考时钟与输入数据信号的跳变相位对齐,可以生成一个恢复的时钟。这被称为时钟恢复。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 2392

YOLO11训练中的过拟合识别与应对策略:讲解过拟合的表现、原因及应对方法(如数据增强、正则化、DropOut)

摘要 本文深入探讨了YOLO11目标检测模型中的过拟合问题。首先解析了过拟合的本质,即模型在训练数据上表现优异但泛化能力差的现象,并通过误差分解公式解释了其数学原理。文章详细列举了YOLO11中过拟合的具体表现,包括训练与验证指标分化、检测性能不一致性、置信度分布异常和类别检测不均衡等问题,并提供了对应的可视化诊断方法。 在原因分析部分,重点阐述了模型复杂度与数据规模不匹配、训练数据质量与分布问题以及训练策略不当三大根本原因。特别对比了YOLO11不同版本(n/s/m/l/x)的参数量和推荐最小数据量,指出

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 245

Polars 与 pandas:Python 数据分析的未来之争

大幅减少 IO 与计算。

chenkaiqiang123的博客 308

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

为什么选 DataComPy?3 行代码对比任意两个 DataFrame 的终极指南

**DataComPy** 是一款 Python 的 **DataFrame 对比工具**,只需 3 行代码就能对比 Pandas、Polars、Spark、Snowflake 等任意两种 DataFrame,并生成人类可读的对比报告。它诞生之初就是为了替代 SAS 的 `PROC COMPARE`,比 `DataFrame.equals()` 更强大——不仅能告诉你"是否相同",还能告诉你"哪里

gitblog_00304的博客 964

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

多维聚合实战:从SQL GROUP BY到OLAP立方体的工程化落地

多维聚合是现代数据分析的核心能力,本质是支持在多个业务维度(如时间、地域、产品)上对度量指标(如销售额、用户数)进行灵活切片、钻取与交叉分析。其技术原理源于OLAP立方体模型,通过维度建模分离分析逻辑与计算逻辑,实现可复用、可扩展、低延迟的聚合能力。相比传统GROUP BY的静态降维,多维聚合具备动态上卷/下钻、热点预计算与实时补算融合等工程优势,广泛应用于BI自助分析、实时用户行为洞察及风控标签体系构建等场景。本文聚焦多维聚合在SQL、Pandas与Polars中的落地实践,覆盖维度建模、GROUPING

weixin_30457465的博客 677

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Pandas连接全指南:从merge到数据契约的工程实践

Pandas连接是数据清洗与整合的核心操作,本质是基于键对齐的表间关系建模。其底层原理涉及索引对齐、内存分配、类型隐式转换及缺失值处理机制。技术价值在于以声明式语法实现复杂数据融合,支撑ETL、用户行为分析、报表生成等关键场景。实际应用中需深度理解how参数的业务语义、validate的数据质量校验能力、indicator的诊断价值,以及on/left_on/right_on等字段对齐策略。本文聚焦真实世界数据挑战——如ID格式不一、空值泛滥、类型错配、重复键冲突等,系统拆解merge、join、conca

weixin_33694172的博客 540
上一篇: 真心建议你一定这样用 pip!
下一篇: 代码片段精选#002:获取嵌套值
codingpy
博客等级 码龄11年 1873粉丝 104原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值