数据框#
本页面提供了所有公共DataFrame方法的概述。
- class polars.DataFrame(
- data: FrameInitTypes | None = None,
- schema: SchemaDefinition | None = None,
- *,
- schema_overrides: SchemaDict | None = None,
- strict: bool = True,
- orient: Orientation | None = None,
- infer_schema_length: int | None = 100,
- nan_to_null: bool = False,
二维数据结构,将数据表示为具有行和列的表。
- Parameters:
- datadict, Sequence, ndarray, Series, or pandas.DataFrame
二维数据以各种形式存在;字典输入必须包含序列、生成器或
range。序列可能包含系列或其他序列。- schemaSequence of str, (str,DataType) pairs, or a {str:DataType,} dict
结果DataFrame的模式。模式可以通过几种方式声明:
作为一个{名称:类型}对的字典;如果类型为None,它将自动推断。
作为列名的列表;在这种情况下,类型会自动推断。
作为(名称,类型)对的列表;这等同于字典形式。
如果您提供的列名列表与基础数据中的名称不匹配,此处提供的名称将覆盖它们。模式中提供的名称数量应与基础数据的维度相匹配。
如果设置为
None(默认值),则从数据中推断出模式。- schema_overridesdict, default None
支持类型指定或覆盖一个或多个列;请注意,从schema参数推断出的任何dtypes将被覆盖。
模式中的条目数量应与基础数据的维度相匹配,除非传递的是字典序列,在这种情况下可以声明部分模式以防止加载特定字段。
- strictbool, default True
如果任何
data值与给定或推断的列数据类型不完全匹配,则抛出错误。如果设置为False,不匹配数据类型的值将被强制转换为该数据类型,或者如果无法转换,则设置为null。- orient{‘col’, ‘row’}, default None
是否将二维数据解释为列或行。如果为None,则通过匹配列和数据维度来推断方向。如果这没有产生确定性的结果,则使用列方向。
- infer_schema_lengthint or None
用于模式推断的最大扫描行数。如果设置为
None,可能会扫描完整数据(这可能会很慢)。此参数仅适用于输入数据为行序列或生成器的情况;其他输入将按原样读取。- nan_to_nullbool, default False
如果数据来自一个或多个numpy数组,可以选择将输入数据中的np.nan值转换为null。对于所有其他输入数据,此操作无效。
注释
Polars 明确不支持其核心数据类型的子类化。有关可能的解决方法,请参阅以下 GitHub 问题: pola-rs/polars#2846
示例
从字典构造一个DataFrame:
>>> data = {"a": [1, 2], "b": [3, 4]} >>> df = pl.DataFrame(data) >>> df shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 3 │ │ 2 ┆ 4 │ └─────┴─────┘
请注意,dtypes 会自动推断为 polars Int64:
>>> df.dtypes [Int64, Int64]
要指定更详细/具体的框架模式,您可以提供
schema参数,该参数是一个包含(名称,数据类型)对的字典…>>> data = {"col1": [0, 2], "col2": [3, 7]} >>> df2 = pl.DataFrame(data, schema={"col1": pl.Float32, "col2": pl.Int64}) >>> df2 shape: (2, 2) ┌──────┬──────┐ │ col1 ┆ col2 │ │ --- ┆ --- │ │ f32 ┆ i64 │ ╞══════╪══════╡ │ 0.0 ┆ 3 │ │ 2.0 ┆ 7 │ └──────┴──────┘
…一系列(名称,数据类型)对…
>>> data = {"col1": [1, 2], "col2": [3, 4]} >>> df3 = pl.DataFrame(data, schema=[("col1", pl.Float32), ("col2", pl.Int64)]) >>> df3 shape: (2, 2) ┌──────┬──────┐ │ col1 ┆ col2 │ │ --- ┆ --- │ │ f32 ┆ i64 │ ╞══════╪══════╡ │ 1.0 ┆ 3 │ │ 2.0 ┆ 4 │ └──────┴──────┘
…或一个类型化Series的列表。
>>> data = [ ... pl.Series("col1", [1, 2], dtype=pl.Float32), ... pl.Series("col2", [3, 4], dtype=pl.Int64), ... ] >>> df4 = pl.DataFrame(data) >>> df4 shape: (2, 2) ┌──────┬──────┐ │ col1 ┆ col2 │ │ --- ┆ --- │ │ f32 ┆ i64 │ ╞══════╪══════╡ │ 1.0 ┆ 3 │ │ 2.0 ┆ 4 │ └──────┴──────┘
从numpy ndarray构建DataFrame,指定列名:
>>> import numpy as np >>> data = np.array([(1, 2), (3, 4)], dtype=np.int64) >>> df5 = pl.DataFrame(data, schema=["a", "b"], orient="col") >>> df5 shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 3 │ │ 2 ┆ 4 │ └─────┴─────┘
从列表的列表中构建DataFrame,指定行方向:
>>> data = [[1, 2, 3], [4, 5, 6]] >>> df6 = pl.DataFrame(data, schema=["a", "b", "c"], orient="row") >>> df6 shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 1 ┆ 2 ┆ 3 │ │ 4 ┆ 5 ┆ 6 │ └─────┴─────┴─────┘
方法:
唯一值的近似计数。
返回
k个最小的行。将DataFrame列转换为指定的数据类型。
创建一个空的(n=0)或
n行空填充(n>0)的DataFrame副本。创建此DataFrame的副本。
获取列名到其数据类型的有序映射。
返回列之间的成对皮尔逊积矩相关系数。
返回每列中非空元素的数量。
DataFrame的汇总统计。
从文件中读取一个序列化的DataFrame。
从数据框中移除列。
就地删除单个列并返回被删除的列。
删除包含一个或多个NaN值的所有行。
删除所有包含空值的行。
检查DataFrame是否等于另一个DataFrame。
返回
DataFrame的总(堆)分配大小的估计值。将数据框通过展开给定列来转换为长格式。
扩展由这个
DataFrame支持的内存,使用other中的值。通过表达式评估填充浮点NaN值。
使用指定的值或策略填充空值。
根据一个或多个谓词表达式过滤DataFrame中的行。
在DataFrame上应用水平缩减。
从DataFrame中每隔n行取一行,并返回一个新的DataFrame。
按名称获取单个列。
按名称查找列的索引。
将DataFrame作为Series的列表获取。
返回DataFrame的密集预览。
开始一个分组操作。
基于时间值(或类型为Int32、Int64的索引值)进行分组。
对此DataFrame中的行进行哈希和组合。
获取前
n行。返回一个新的DataFrame,通过将多个Series水平堆叠来扩展它。
在某个列索引处插入一个Series。
插值中间值。
获取此DataFrame中所有重复行的掩码。
如果DataFrame不包含任何行,则返回
True。获取此DataFrame中所有唯一行的掩码。
将DataFrame作为标量返回,或返回给定行/列的元素。
返回此DataFrame列的迭代器。
返回一个迭代器,用于遍历由Python原生值组成的DataFrame行。
返回一个不复制底层DataFrame切片的迭代器。
以类似SQL的方式连接。
执行一个asof连接。
基于一个或多个(不)等式谓词执行连接。
从这一点开始一个惰性查询。
获取前
n行。在DataFrame的行上应用自定义/用户定义的函数(UDF)。
将此DataFrame的列聚合到它们的最大值。
获取列之间的水平最大值。
将此DataFrame的列聚合为其平均值。
取所有值在列之间的水平平均值。
将此DataFrame的列聚合到它们的中值。
将DataFrame从宽格式转换为长格式。
取两个已排序的DataFrame并按排序键合并它们。
将此DataFrame的列聚合到它们的最小值。
获取列之间的水平最小值。
获取此DataFrame的ChunkedArrays使用的块数。
返回唯一行的数量,或唯一行子集的数量。
创建一个新的DataFrame,显示每列的空值计数。
按给定的列进行分组,并将分组作为单独的数据框返回。
提供了一种结构化的方式来应用一系列用户定义的函数(UDFs)。
创建一个电子表格样式的数据透视表作为DataFrame。
将此DataFrame的列聚合为其乘积值。
将此DataFrame的列聚合到它们的分位数值。
将此DataFrame中的数据重新分块为连续分配。
重命名列名。
在索引位置替换一列。
反转DataFrame。
基于时间或整数列创建滚动组。
通过索引或谓词获取单行的值。
返回DataFrame中的所有数据作为Python原生值的行列表。
返回所有数据作为以某列作为键的Python原生值的字典。
从这个DataFrame中取样。
从这个DataFrame中选择列。
从这个DataFrame中选择列。
将此DataFrame序列化为JSON格式的文件或字符串。
指示一个或多个列已排序。
将值按给定的索引数进行移动。
缩小DataFrame的内存使用。
获取此DataFrame的一个切片。
按给定的列对数据框进行排序。
对DataFrame执行SQL查询。
将此DataFrame的列聚合为其标准差值。
将此DataFrame的列聚合为其总和值。
水平跨列求和所有值。
获取最后
n行。收集Arrow表中的底层箭头数组。
将DataFrame转换为列名到值的字典映射。
将每一行转换为Python原生值的字典。
将分类变量转换为虚拟/指示变量。
将DataFrame转换为可实例化的字符串表示。
将DataFrame转换为Jax数组,或Jax数组的字典。
将此DataFrame转换为NumPy ndarray。
将此DataFrame转换为pandas DataFrame。
在索引位置选择列作为Series。
将
DataFrame转换为类型为Struct的Series。将DataFrame转换为PyTorch张量、数据集或张量字典。
返回
k个最大的行。将DataFrame沿对角线进行转置。
从这个数据框中删除重复的行。
将结构体列分解为每个字段的单独列。
将DataFrame从宽格式转换为长格式。
将长表展开为宽表形式,而不进行聚合操作。
使用
other中的值更新此DataFrame中的值。以固定频率对DataFrame进行上采样。
将此DataFrame的列聚合为其方差值。
通过将一个DataFrame堆叠到它上面,垂直扩展这个DataFrame。
向此DataFrame添加列。
向此DataFrame添加列。
在第0列添加一个用于计算行数的列。
在DataFrame中添加一行索引作为第一列。
写入Apache Avro文件。
将
DataFrame以csv格式复制到系统剪贴板,使用write_csv。写入逗号分隔值(CSV)文件。
将Polars DataFrame中的数据写入数据库。
将DataFrame写入为delta表。
将框架数据写入Excel工作簿/工作表中的表格。
写入Arrow IPC二进制流或Feather文件。
写入Arrow IPC记录批次流。
序列化为JSON表示。
序列化为换行符分隔的JSON表示。
写入Apache Parquet文件。
属性:
获取或设置列名。
获取列数据类型。
获取在此DataFrame的列上设置的标志。
获取行数。
创建一个绘图命名空间。
获取列名到其数据类型的有序映射。
获取DataFrame的形状。
创建一个用于样式设计的优秀表格。
获取列数。
- approx_n_unique() DataFrame[source]
唯一值的近似计数。
自版本0.20.11起已弃用:请改用
select(pl.all().approx_n_unique())。这是使用HyperLogLog++算法进行基数估计的。
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 4], ... "b": [1, 2, 1, 1], ... } ... ) >>> df.approx_n_unique() shape: (1, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ u32 ┆ u32 │ ╞═════╪═════╡ │ 4 ┆ 2 │ └─────┴─────┘
- bottom_k( ) DataFrame[source]
返回
k个最小的行。非空元素总是优先于空元素,无论
reverse的值如何。输出不保证按任何特定顺序排列,如果您希望输出排序,请在此函数之后调用sort()。- Parameters:
- k
返回的行数。
- by
用于确定底部行的列。 接受表达式输入。字符串被解析为列名。
- reverse
考虑
by列中的k个最大元素(而不是k个最小元素)。可以通过传递一个布尔值序列来为每列指定这一点。
另请参阅
示例
>>> df = pl.DataFrame( ... { ... "a": ["a", "b", "a", "b", "b", "c"], ... "b": [2, 1, 1, 3, 2, 1], ... } ... )
获取包含列b中4个最小值的行。
>>> df.bottom_k(4, by="b") shape: (4, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ str ┆ i64 │ ╞═════╪═════╡ │ b ┆ 1 │ │ a ┆ 1 │ │ c ┆ 1 │ │ a ┆ 2 │ └─────┴─────┘
获取在列a和b上排序时包含4个最小值的行。
>>> df.bottom_k(4, by=["a", "b"]) shape: (4, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ str ┆ i64 │ ╞═════╪═════╡ │ a ┆ 1 │ │ a ┆ 2 │ │ b ┆ 1 │ │ b ┆ 2 │ └─────┴─────┘
- cast(
- dtypes: Mapping[ColumnNameOrSelector | PolarsDataType, PolarsDataType | PythonDataType] | PolarsDataType,
- *,
- strict: bool = True,
将DataFrame列转换为指定的数据类型。
- Parameters:
- dtypes
列名(或选择器)到数据类型的映射,或所有列将被转换的单一数据类型。
- strict
如果在谓词下推后对行的转换无效,则引发异常。 如果
False,无效的转换将产生空值。
示例
>>> from datetime import date >>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": [date(2020, 1, 2), date(2021, 3, 4), date(2022, 5, 6)], ... } ... )
将特定的帧列转换为指定的数据类型:
>>> df.cast({"foo": pl.Float32, "bar": pl.UInt8}) shape: (3, 3) ┌─────┬─────┬────────────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f32 ┆ u8 ┆ date │ ╞═════╪═════╪════════════╡ │ 1.0 ┆ 6 ┆ 2020-01-02 │ │ 2.0 ┆ 7 ┆ 2021-03-04 │ │ 3.0 ┆ 8 ┆ 2022-05-06 │ └─────┴─────┴────────────┘
将所有匹配一种数据类型(或数据类型组)的框架列转换为另一种数据类型:
>>> df.cast({pl.Date: pl.Datetime}) shape: (3, 3) ┌─────┬─────┬─────────────────────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ datetime[μs] │ ╞═════╪═════╪═════════════════════╡ │ 1 ┆ 6.0 ┆ 2020-01-02 00:00:00 │ │ 2 ┆ 7.0 ┆ 2021-03-04 00:00:00 │ │ 3 ┆ 8.0 ┆ 2022-05-06 00:00:00 │ └─────┴─────┴─────────────────────┘
使用选择器来定义要转换的列:
>>> import polars.selectors as cs >>> df.cast({cs.numeric(): pl.UInt32, cs.temporal(): pl.String}) shape: (3, 3) ┌─────┬─────┬────────────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ u32 ┆ u32 ┆ str │ ╞═════╪═════╪════════════╡ │ 1 ┆ 6 ┆ 2020-01-02 │ │ 2 ┆ 7 ┆ 2021-03-04 │ │ 3 ┆ 8 ┆ 2022-05-06 │ └─────┴─────┴────────────┘
将所有框架列转换为指定的数据类型:
>>> df.cast(pl.String).to_dict(as_series=False) {'foo': ['1', '2', '3'], 'bar': ['6.0', '7.0', '8.0'], 'ham': ['2020-01-02', '2021-03-04', '2022-05-06']}
- clear(n: int = 0) DataFrame[source]
创建一个空的(n=0)或
n行空填充(n>0)的DataFrame副本。返回一个具有相同模式的
n行空填充的DataFrame。n可以大于DataFrame中当前的行数。- Parameters:
- n
返回清除框架中的(空填充)行数。
另请参阅
clone便宜的深拷贝/克隆。
示例
>>> df = pl.DataFrame( ... { ... "a": [None, 2, 3, 4], ... "b": [0.5, None, 2.5, 13], ... "c": [True, True, False, None], ... } ... ) >>> df.clear() shape: (0, 3) ┌─────┬─────┬──────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ bool │ ╞═════╪═════╪══════╡ └─────┴─────┴──────┘
>>> df.clear(n=2) shape: (2, 3) ┌──────┬──────┬──────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ bool │ ╞══════╪══════╪══════╡ │ null ┆ null ┆ null │ │ null ┆ null ┆ null │ └──────┴──────┴──────┘
- clone() DataFrame[source]
创建此DataFrame的副本。
这是一个不复制数据的廉价操作。
另请参阅
clear创建一个当前DataFrame的空副本,具有相同的模式但没有数据。
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 4], ... "b": [0.5, 4, 10, 13], ... "c": [True, True, False, True], ... } ... ) >>> df.clone() shape: (4, 3) ┌─────┬──────┬───────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ bool │ ╞═════╪══════╪═══════╡ │ 1 ┆ 0.5 ┆ true │ │ 2 ┆ 4.0 ┆ true │ │ 3 ┆ 10.0 ┆ false │ │ 4 ┆ 13.0 ┆ true │ └─────┴──────┴───────┘
- collect_schema() Schema[source]
获取列名到其数据类型的有序映射。
这是
schema属性的别名。另请参阅
注释
此方法被包含以便于编写对DataFrame和LazyFrame都通用的代码。
示例
确定模式。
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.collect_schema() Schema({'foo': Int64, 'bar': Float64, 'ham': String})
使用
Schema对象访问模式的各种属性。>>> schema = df.collect_schema() >>> schema["bar"] Float64 >>> schema.names() ['foo', 'bar', 'ham'] >>> schema.dtypes() [Int64, Float64, String] >>> schema.len() 3
- property columns: list[str][source]
获取或设置列名。
- Returns:
- list of str
包含每列名称的列表,按顺序排列。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.columns ['foo', 'bar', 'ham']
设置列名:
>>> df.columns = ["apple", "banana", "orange"] >>> df shape: (3, 3) ┌───────┬────────┬────────┐ │ apple ┆ banana ┆ orange │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═══════╪════════╪════════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ └───────┴────────┴────────┘
- corr(**kwargs: Any) DataFrame[source]
返回列之间的成对皮尔逊积矩相关系数。
有关更多信息,请参见 numpy
corrcoef: https://numpy.org/doc/stable/reference/generated/numpy.corrcoef.html- Parameters:
- **kwargs
关键字参数被传递给 numpy 的
corrcoef。
注释
此功能需要安装numpy。
示例
>>> df = pl.DataFrame({"foo": [1, 2, 3], "bar": [3, 2, 1], "ham": [7, 8, 9]}) >>> df.corr() shape: (3, 3) ┌──────┬──────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ f64 │ ╞══════╪══════╪══════╡ │ 1.0 ┆ -1.0 ┆ 1.0 │ │ -1.0 ┆ 1.0 ┆ -1.0 │ │ 1.0 ┆ -1.0 ┆ 1.0 │ └──────┴──────┴──────┘
- count() DataFrame[source]
返回每列中非空元素的数量。
示例
>>> df = pl.DataFrame( ... {"a": [1, 2, 3, 4], "b": [1, 2, 1, None], "c": [None, None, None, None]} ... ) >>> df.count() shape: (1, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ u32 ┆ u32 ┆ u32 │ ╞═════╪═════╪═════╡ │ 4 ┆ 3 ┆ 0 │ └─────┴─────┴─────┘
- describe(
- percentiles: Sequence[float] | float | None = (0.25, 0.5, 0.75),
- *,
- interpolation: RollingInterpolationMethod = 'nearest',
DataFrame的汇总统计。
- Parameters:
- percentiles
要包含在汇总统计中的一个或多个百分位数。 所有值必须在
[0, 1]范围内。- interpolation{‘nearest’, ‘higher’, ‘lower’, ‘midpoint’, ‘linear’}
计算百分位数时使用的插值方法。
警告
我们不保证
describe的输出是稳定的。它将显示我们认为有信息量的统计信息,并且可能会在未来更新。因此,不建议以编程方式使用describe(相对于交互式探索)。另请参阅
注释
默认情况下,中位数作为50%百分位数被包含在内。
示例
>>> from datetime import date, time >>> df = pl.DataFrame( ... { ... "float": [1.0, 2.8, 3.0], ... "int": [40, 50, None], ... "bool": [True, False, True], ... "str": ["zz", "xx", "yy"], ... "date": [date(2020, 1, 1), date(2021, 7, 5), date(2022, 12, 31)], ... "time": [time(10, 20, 30), time(14, 45, 50), time(23, 15, 10)], ... } ... )
显示默认帧统计信息:
>>> df.describe() shape: (9, 7) ┌────────────┬──────────┬──────────┬──────────┬──────┬─────────────────────┬──────────┐ │ statistic ┆ float ┆ int ┆ bool ┆ str ┆ date ┆ time │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ f64 ┆ f64 ┆ f64 ┆ str ┆ str ┆ str │ ╞════════════╪══════════╪══════════╪══════════╪══════╪═════════════════════╪══════════╡ │ count ┆ 3.0 ┆ 2.0 ┆ 3.0 ┆ 3 ┆ 3 ┆ 3 │ │ null_count ┆ 0.0 ┆ 1.0 ┆ 0.0 ┆ 0 ┆ 0 ┆ 0 │ │ mean ┆ 2.266667 ┆ 45.0 ┆ 0.666667 ┆ null ┆ 2021-07-02 16:00:00 ┆ 16:07:10 │ │ std ┆ 1.101514 ┆ 7.071068 ┆ null ┆ null ┆ null ┆ null │ │ min ┆ 1.0 ┆ 40.0 ┆ 0.0 ┆ xx ┆ 2020-01-01 ┆ 10:20:30 │ │ 25% ┆ 2.8 ┆ 40.0 ┆ null ┆ null ┆ 2021-07-05 ┆ 14:45:50 │ │ 50% ┆ 2.8 ┆ 50.0 ┆ null ┆ null ┆ 2021-07-05 ┆ 14:45:50 │ │ 75% ┆ 3.0 ┆ 50.0 ┆ null ┆ null ┆ 2022-12-31 ┆ 23:15:10 │ │ max ┆ 3.0 ┆ 50.0 ┆ 1.0 ┆ zz ┆ 2022-12-31 ┆ 23:15:10 │ └────────────┴──────────┴──────────┴──────────┴──────┴─────────────────────┴──────────┘
自定义显示的百分位数,应用线性插值:
>>> with pl.Config(tbl_rows=12): ... df.describe( ... percentiles=[0.1, 0.3, 0.5, 0.7, 0.9], ... interpolation="linear", ... ) shape: (11, 7) ┌────────────┬──────────┬──────────┬──────────┬──────┬─────────────────────┬──────────┐ │ statistic ┆ float ┆ int ┆ bool ┆ str ┆ date ┆ time │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ f64 ┆ f64 ┆ f64 ┆ str ┆ str ┆ str │ ╞════════════╪══════════╪══════════╪══════════╪══════╪═════════════════════╪══════════╡ │ count ┆ 3.0 ┆ 2.0 ┆ 3.0 ┆ 3 ┆ 3 ┆ 3 │ │ null_count ┆ 0.0 ┆ 1.0 ┆ 0.0 ┆ 0 ┆ 0 ┆ 0 │ │ mean ┆ 2.266667 ┆ 45.0 ┆ 0.666667 ┆ null ┆ 2021-07-02 16:00:00 ┆ 16:07:10 │ │ std ┆ 1.101514 ┆ 7.071068 ┆ null ┆ null ┆ null ┆ null │ │ min ┆ 1.0 ┆ 40.0 ┆ 0.0 ┆ xx ┆ 2020-01-01 ┆ 10:20:30 │ │ 10% ┆ 1.36 ┆ 41.0 ┆ null ┆ null ┆ 2020-04-20 ┆ 11:13:34 │ │ 30% ┆ 2.08 ┆ 43.0 ┆ null ┆ null ┆ 2020-11-26 ┆ 12:59:42 │ │ 50% ┆ 2.8 ┆ 45.0 ┆ null ┆ null ┆ 2021-07-05 ┆ 14:45:50 │ │ 70% ┆ 2.88 ┆ 47.0 ┆ null ┆ null ┆ 2022-02-07 ┆ 18:09:34 │ │ 90% ┆ 2.96 ┆ 49.0 ┆ null ┆ null ┆ 2022-09-13 ┆ 21:33:18 │ │ max ┆ 3.0 ┆ 50.0 ┆ 1.0 ┆ zz ┆ 2022-12-31 ┆ 23:15:10 │ └────────────┴──────────┴──────────┴──────────┴──────┴─────────────────────┴──────────┘
- classmethod deserialize(
- source: str | Path | IOBase,
- *,
- format: SerializationFormat = 'binary',
从文件中读取一个序列化的DataFrame。
- Parameters:
- source
文件路径或类文件对象(类文件对象指的是具有
read()方法的对象,例如文件句柄(如通过内置的open函数)或BytesIO)。- format
DataFrame 被序列化的格式。选项:
"binary": 从二进制格式(字节)反序列化。这是默认设置。"json": 从JSON格式(字符串)反序列化。
另请参阅
注释
序列化在Polars版本之间不稳定:在一个Polars版本中序列化的LazyFrame可能无法在另一个Polars版本中反序列化。
示例
>>> import io >>> df = pl.DataFrame({"a": [1, 2, 3], "b": [4.0, 5.0, 6.0]}) >>> bytes = df.serialize() >>> pl.DataFrame.deserialize(io.BytesIO(bytes)) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ f64 │ ╞═════╪═════╡ │ 1 ┆ 4.0 │ │ 2 ┆ 5.0 │ │ 3 ┆ 6.0 │ └─────┴─────┘
- drop(
- *columns: ColumnNameOrSelector | Iterable[ColumnNameOrSelector],
- strict: bool = True,
从数据框中移除列。
- Parameters:
- *columns
应从数据框中删除的列名。 接受列选择器输入。
- strict
验证当前模式中是否存在所有列名,如果不存在则抛出异常。
示例
通过传递列的名称来删除单个列。
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.drop("ham") shape: (3, 2) ┌─────┬─────┐ │ foo ┆ bar │ │ --- ┆ --- │ │ i64 ┆ f64 │ ╞═════╪═════╡ │ 1 ┆ 6.0 │ │ 2 ┆ 7.0 │ │ 3 ┆ 8.0 │ └─────┴─────┘
通过传递列名列表来删除多个列。
>>> df.drop(["bar", "ham"]) shape: (3, 1) ┌─────┐ │ foo │ │ --- │ │ i64 │ ╞═════╡ │ 1 │ │ 2 │ │ 3 │ └─────┘
通过传递选择器删除多个列。
>>> import polars.selectors as cs >>> df.drop(cs.numeric()) shape: (3, 1) ┌─────┐ │ ham │ │ --- │ │ str │ ╞═════╡ │ a │ │ b │ │ c │ └─────┘
使用位置参数来删除多个列。
>>> df.drop("foo", "ham") shape: (3, 1) ┌─────┐ │ bar │ │ --- │ │ f64 │ ╞═════╡ │ 6.0 │ │ 7.0 │ │ 8.0 │ └─────┘
- drop_in_place(name: str) Series[source]
就地删除单个列并返回被删除的列。
- Parameters:
- name
要删除的列的名称。
- Returns:
- Series
被删除的列。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.drop_in_place("ham") shape: (3,) Series: 'ham' [str] [ "a" "b" "c" ]
- drop_nans(
- subset: ColumnNameOrSelector | Collection[ColumnNameOrSelector] | None = None,
删除包含一个或多个NaN值的所有行。
剩余行的原始顺序保持不变。
- Parameters:
- subset
考虑NaN值的列名;如果设置为
None(默认),则使用所有列(注意只有浮点数列可以包含NaN)。
示例
>>> df = pl.DataFrame( ... { ... "foo": [-20.5, float("nan"), 80.0], ... "bar": [float("nan"), 110.0, 25.5], ... "ham": ["xxx", "yyy", None], ... } ... )
此方法的默认行为是删除行中任何单个值为NaN的行:
>>> df.drop_nans() shape: (1, 3) ┌──────┬──────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str │ ╞══════╪══════╪══════╡ │ 80.0 ┆ 25.5 ┆ null │ └──────┴──────┴──────┘
这种行为可以被限制为仅考虑由名称定义的列的子集,或者使用选择器。例如,仅在“bar”列中存在NaN时删除行:
>>> df.drop_nans(subset=["bar"]) shape: (2, 3) ┌──────┬───────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str │ ╞══════╪═══════╪══════╡ │ NaN ┆ 110.0 ┆ yyy │ │ 80.0 ┆ 25.5 ┆ null │ └──────┴───────┴──────┘
只有当所有值都是NaN时,才删除一行,这需要不同的公式:
>>> df = pl.DataFrame( ... { ... "a": [float("nan"), float("nan"), float("nan"), float("nan")], ... "b": [10.0, 2.5, float("nan"), 5.25], ... "c": [65.75, float("nan"), float("nan"), 10.5], ... } ... ) >>> df.filter(~pl.all_horizontal(pl.all().is_nan())) shape: (3, 3) ┌─────┬──────┬───────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ f64 │ ╞═════╪══════╪═══════╡ │ NaN ┆ 10.0 ┆ 65.75 │ │ NaN ┆ 2.5 ┆ NaN │ │ NaN ┆ 5.25 ┆ 10.5 │ └─────┴──────┴───────┘
- drop_nulls(
- subset: ColumnNameOrSelector | Collection[ColumnNameOrSelector] | None = None,
删除所有包含空值的行。
剩余行的原始顺序保持不变。
- Parameters:
- subset
考虑空值的列名。 如果设置为
None(默认),则使用所有列。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, None, 8], ... "ham": ["a", "b", None], ... } ... )
此方法的默认行为是删除行中任何单个值为空的行。
>>> df.drop_nulls() shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ └─────┴─────┴─────┘
这种行为可以被限制为仅考虑由名称或选择器定义的列的子集。例如,如果任何整数列中存在空值,则删除行:
>>> import polars.selectors as cs >>> df.drop_nulls(subset=cs.integer()) shape: (2, 3) ┌─────┬─────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪══════╡ │ 1 ┆ 6 ┆ a │ │ 3 ┆ 8 ┆ null │ └─────┴─────┴──────┘
以下是一些额外的示例,展示了如何根据其他条件删除空值。
>>> df = pl.DataFrame( ... { ... "a": [None, None, None, None], ... "b": [1, 2, None, 1], ... "c": [1, None, None, 1], ... } ... ) >>> df shape: (4, 3) ┌──────┬──────┬──────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ null ┆ i64 ┆ i64 │ ╞══════╪══════╪══════╡ │ null ┆ 1 ┆ 1 │ │ null ┆ 2 ┆ null │ │ null ┆ null ┆ null │ │ null ┆ 1 ┆ 1 │ └──────┴──────┴──────┘
仅当所有值都为null时删除一行:
>>> df.filter(~pl.all_horizontal(pl.all().is_null())) shape: (3, 3) ┌──────┬─────┬──────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ null ┆ i64 ┆ i64 │ ╞══════╪═════╪══════╡ │ null ┆ 1 ┆ 1 │ │ null ┆ 2 ┆ null │ │ null ┆ 1 ┆ 1 │ └──────┴─────┴──────┘
如果所有值都为null,则删除列:
>>> df[[s.name for s in df if not (s.null_count() == df.height)]] shape: (4, 2) ┌──────┬──────┐ │ b ┆ c │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞══════╪══════╡ │ 1 ┆ 1 │ │ 2 ┆ null │ │ null ┆ null │ │ 1 ┆ 1 │ └──────┴──────┘
- property dtypes: list[DataType][source]
获取列数据类型。
在打印DataFrame时,数据类型也可以在列标题中找到。
- Returns:
- list of DataType
一个包含每列数据类型的列表,按顺序排列。
另请参阅
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.dtypes [Int64, Float64, String] >>> df shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6.0 ┆ a │ │ 2 ┆ 7.0 ┆ b │ │ 3 ┆ 8.0 ┆ c │ └─────┴─────┴─────┘
- equals(
- other: DataFrame,
- *,
- null_equal: bool = True,
检查DataFrame是否等于另一个DataFrame。
- Parameters:
- other
要与之比较的DataFrame。
- null_equal
将空值视为相等。
示例
>>> df1 = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": ["a", "b", "c"], ... } ... ) >>> df2 = pl.DataFrame( ... { ... "foo": [3, 2, 1], ... "bar": [8.0, 7.0, 6.0], ... "ham": ["c", "b", "a"], ... } ... ) >>> df1.equals(df1) True >>> df1.equals(df2) False
- estimated_size(unit: SizeUnit = 'b') int | float[source]
返回
DataFrame的总(堆)分配大小的估计值。估计大小以指定单位给出(默认为字节)。
此估计是其缓冲区大小、有效性的总和,包括嵌套数组。多个数组可能共享缓冲区和位图。因此,两个数组的大小不是从此函数计算出的尺寸的总和。特别是,[
StructArray]的大小是一个上限。当数组被切片时,其分配的大小保持不变,因为缓冲区未改变。然而,此函数将返回一个较小的数字。这是因为此函数返回缓冲区的可见大小,而不是其总容量。
FFI缓冲区包含在此估计中。
- Parameters:
- unit{‘b’, ‘kb’, ‘mb’, ‘gb’, ‘tb’}
将返回的大小缩放到给定的单位。
示例
>>> df = pl.DataFrame( ... { ... "x": list(reversed(range(1_000_000))), ... "y": [v / 1000 for v in range(1_000_000)], ... "z": [str(v) for v in range(1_000_000)], ... }, ... schema=[("x", pl.UInt32), ("y", pl.Float64), ("z", pl.String)], ... ) >>> df.estimated_size() 17888890 >>> df.estimated_size("mb") 17.0601749420166
- explode( ) DataFrame[source]
将数据框通过展开给定列来转换为长格式。
- Parameters:
- columns
列名、表达式或定义它们的选择器。被展开的底层列必须是
List或Array数据类型。- *more_columns
要展开的额外列名,指定为位置参数。
- Returns:
- DataFrame
示例
>>> df = pl.DataFrame( ... { ... "letters": ["a", "a", "b", "c"], ... "numbers": [[1], [2, 3], [4, 5], [6, 7, 8]], ... } ... ) >>> df shape: (4, 2) ┌─────────┬───────────┐ │ letters ┆ numbers │ │ --- ┆ --- │ │ str ┆ list[i64] │ ╞═════════╪═══════════╡ │ a ┆ [1] │ │ a ┆ [2, 3] │ │ b ┆ [4, 5] │ │ c ┆ [6, 7, 8] │ └─────────┴───────────┘ >>> df.explode("numbers") shape: (8, 2) ┌─────────┬─────────┐ │ letters ┆ numbers │ │ --- ┆ --- │ │ str ┆ i64 │ ╞═════════╪═════════╡ │ a ┆ 1 │ │ a ┆ 2 │ │ a ┆ 3 │ │ b ┆ 4 │ │ b ┆ 5 │ │ c ┆ 6 │ │ c ┆ 7 │ │ c ┆ 8 │ └─────────┴─────────┘
- extend(
- other: DataFrame,
扩展由这个
DataFrame支持的内存,使用other中的值。与
vstack不同,它将other的块添加到这个DataFrame的块中,extend将other的数据追加到底层内存位置,因此可能会导致重新分配。如果这不会导致重新分配,生成的数据结构将不会有任何额外的块,因此查询速度会更快。
当您希望在单个追加操作后执行查询时,优先使用
extend而不是vstack。例如,在在线操作期间,您添加n行并重新运行查询。在进行查询之前,如果您想要多次追加,建议使用
vstack而不是extend。例如,当您读取多个文件并希望将它们存储在单个DataFrame中时。在后一种情况下,使用rechunk完成一系列vstack操作。- Parameters:
- other
要垂直添加的DataFrame。
警告
此方法会就地修改数据框。返回数据框仅为了方便。
另请参阅
示例
>>> df1 = pl.DataFrame({"foo": [1, 2, 3], "bar": [4, 5, 6]}) >>> df2 = pl.DataFrame({"foo": [10, 20, 30], "bar": [40, 50, 60]}) >>> df1.extend(df2) shape: (6, 2) ┌─────┬─────┐ │ foo ┆ bar │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 4 │ │ 2 ┆ 5 │ │ 3 ┆ 6 │ │ 10 ┆ 40 │ │ 20 ┆ 50 │ │ 30 ┆ 60 │ └─────┴─────┘
- fill_nan(value: Expr | int | float | None) DataFrame[source]
通过表达式评估填充浮点NaN值。
- Parameters:
- value
用于替换NaN值的值。
- Returns:
- DataFrame
DataFrame 中的 NaN 值已被给定值替换。
警告
请注意,浮点数的NaN(非数字)不是缺失值。 要替换缺失值,请使用
fill_null()。另请参阅
示例
>>> df = pl.DataFrame( ... { ... "a": [1.5, 2, float("nan"), 4], ... "b": [0.5, 4, float("nan"), 13], ... } ... ) >>> df.fill_nan(99) shape: (4, 2) ┌──────┬──────┐ │ a ┆ b │ │ --- ┆ --- │ │ f64 ┆ f64 │ ╞══════╪══════╡ │ 1.5 ┆ 0.5 │ │ 2.0 ┆ 4.0 │ │ 99.0 ┆ 99.0 │ │ 4.0 ┆ 13.0 │ └──────┴──────┘
- fill_null(
- value: Any | Expr | None = None,
- strategy: FillNullStrategy | None = None,
- limit: int | None = None,
- *,
- matches_supertype: bool = True,
使用指定的值或策略填充空值。
- Parameters:
- value
用于填充空值的值。
- strategy{None, ‘forward’, ‘backward’, ‘min’, ‘max’, ‘mean’, ‘zero’, ‘one’}
用于填充空值的策略。
- limit
使用‘forward’或‘backward’策略时,要填充的连续空值的数量。
- matches_supertype
填充所有匹配的超类型的填充
value。
- Returns:
- DataFrame
DataFrame 中的 None 值被填充策略替换。
另请参阅
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 2, None, 4], ... "b": [0.5, 4, None, 13], ... } ... ) >>> df.fill_null(99) shape: (4, 2) ┌─────┬──────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ f64 │ ╞═════╪══════╡ │ 1 ┆ 0.5 │ │ 2 ┆ 4.0 │ │ 99 ┆ 99.0 │ │ 4 ┆ 13.0 │ └─────┴──────┘ >>> df.fill_null(strategy="forward") shape: (4, 2) ┌─────┬──────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ f64 │ ╞═════╪══════╡ │ 1 ┆ 0.5 │ │ 2 ┆ 4.0 │ │ 2 ┆ 4.0 │ │ 4 ┆ 13.0 │ └─────┴──────┘
>>> df.fill_null(strategy="max") shape: (4, 2) ┌─────┬──────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ f64 │ ╞═════╪══════╡ │ 1 ┆ 0.5 │ │ 2 ┆ 4.0 │ │ 4 ┆ 13.0 │ │ 4 ┆ 13.0 │ └─────┴──────┘
>>> df.fill_null(strategy="zero") shape: (4, 2) ┌─────┬──────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ f64 │ ╞═════╪══════╡ │ 1 ┆ 0.5 │ │ 2 ┆ 4.0 │ │ 0 ┆ 0.0 │ │ 4 ┆ 13.0 │ └─────┴──────┘
- filter(
- *predicates: IntoExprColumn | Iterable[IntoExprColumn] | bool | list[bool] | np.ndarray[Any, Any],
- **constraints: Any,
根据一个或多个谓词表达式过滤DataFrame中的行。
剩余行的原始顺序保持不变。
过滤器未评估为True的行将被丢弃,包括空值。
- Parameters:
- predicates
评估为布尔系列的表达式。
- constraints
列过滤器;使用
name = value通过提供的值过滤列。 每个约束的行为将与pl.col(name).eq(value)相同,并且 将使用&隐式地与其他过滤条件连接。
注释
如果您正在从pandas过渡并根据两列或多列的比较执行过滤操作,请注意在Polars中,任何涉及空值的比较都将始终导致空值。因此,这些行将被过滤掉。请确保适当处理空值,以避免意外的过滤(请参见下面的示例)。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, None, 4, None, 0], ... "bar": [6, 7, 8, None, None, 9, 0], ... "ham": ["a", "b", "c", None, "d", "e", "f"], ... } ... )
根据一个条件进行筛选:
>>> df.filter(pl.col("foo") > 1) shape: (3, 3) ┌─────┬──────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪══════╪═════╡ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ │ 4 ┆ null ┆ d │ └─────┴──────┴─────┘
根据多个条件进行过滤,结合与/或运算符:
>>> df.filter((pl.col("foo") < 3) & (pl.col("ham") == "a")) shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ └─────┴─────┴─────┘
>>> df.filter((pl.col("foo") == 1) | (pl.col("ham") == "c")) shape: (2, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 3 ┆ 8 ┆ c │ └─────┴─────┴─────┘
使用
*args语法提供多个过滤器:>>> df.filter( ... pl.col("foo") <= 2, ... ~pl.col("ham").is_in(["b", "c"]), ... ) shape: (2, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 0 ┆ 0 ┆ f │ └─────┴─────┴─────┘
使用
**kwargs语法提供多个过滤器:>>> df.filter(foo=2, ham="b") shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 2 ┆ 7 ┆ b │ └─────┴─────┴─────┘
通过比较两列进行筛选
>>> df.filter(pl.col("foo") == pl.col("bar")) shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 0 ┆ 0 ┆ f │ └─────┴─────┴─────┘
>>> df.filter(pl.col("foo") != pl.col("bar")) shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ └─────┴─────┴─────┘
注意带有
None值的行是如何被过滤掉的。为了保持与pandas相同的行为,请使用:>>> df.filter(pl.col("foo").ne_missing(pl.col("bar"))) shape: (5, 3) ┌──────┬──────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞══════╪══════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ │ 4 ┆ null ┆ d │ │ null ┆ 9 ┆ e │ └──────┴──────┴─────┘
- fold(operation: Callable[[Series, Series], Series]) Series[source]
在DataFrame上应用水平缩减。
这可以有效地用于确定行级别的聚合,并且可以应用于任何可以超级转换(转换为类似的父类型)的数据类型。
在对两种数据类型应用算术运算时,超级转换规则的示例如下:
Int8 + 字符串 = 字符串
Float32 + Int64 = Float32
Float32 + Float64 = Float64
- Parameters:
- operation
接受两个
Series并返回一个Series的函数。
示例
水平求和操作:
>>> df = pl.DataFrame( ... { ... "a": [2, 1, 3], ... "b": [1, 2, 3], ... "c": [1.0, 2.0, 3.0], ... } ... ) >>> df.fold(lambda s1, s2: s1 + s2) shape: (3,) Series: 'a' [f64] [ 4.0 5.0 9.0 ]
水平最小操作:
>>> df = pl.DataFrame({"a": [2, 1, 3], "b": [1, 2, 3], "c": [1.0, 2.0, 3.0]}) >>> df.fold(lambda s1, s2: s1.zip_with(s1 < s2, s2)) shape: (3,) Series: 'a' [f64] [ 1.0 1.0 3.0 ]
水平字符串连接:
>>> df = pl.DataFrame( ... { ... "a": ["foo", "bar", None], ... "b": [1, 2, 3], ... "c": [1.0, 2.0, 3.0], ... } ... ) >>> df.fold(lambda s1, s2: s1 + s2) shape: (3,) Series: 'a' [str] [ "foo11.0" "bar22.0" null ]
一个水平布尔或,类似于逐行的 .any():
>>> df = pl.DataFrame( ... { ... "a": [False, False, True], ... "b": [False, True, False], ... } ... ) >>> df.fold(lambda s1, s2: s1 | s2) shape: (3,) Series: 'a' [bool] [ false true true ]
- gather_every(n: int, offset: int = 0) DataFrame[source]
从DataFrame中每隔n行取一行,并返回一个新的DataFrame。
- Parameters:
- n
收集每n行。
- offset
起始索引。
示例
>>> s = pl.DataFrame({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) >>> s.gather_every(2) shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 5 │ │ 3 ┆ 7 │ └─────┴─────┘
>>> s.gather_every(2, offset=1) shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 2 ┆ 6 │ │ 4 ┆ 8 │ └─────┴─────┘
- get_column(
- name: str,
- *,
- default: Any | NoDefault = <no_default>,
按名称获取单个列。
- Parameters:
- name
要检索的列的字符串名称。
- default
如果列不存在时返回的值;如果没有明确设置且列不存在,则会引发
ColumnNotFoundError异常。
- Returns:
- Series (or arbitrary default value, if specified).
另请参阅
示例
>>> df = pl.DataFrame({"foo": [1, 2, 3], "bar": [4, 5, 6]}) >>> df.get_column("foo") shape: (3,) Series: 'foo' [i64] [ 1 2 3 ]
缺失列处理;可以选择为方法提供一个任意的默认值(否则会引发
ColumnNotFoundError异常)。>>> df.get_column("baz", default=pl.Series("baz", ["?", "?", "?"])) shape: (3,) Series: 'baz' [str] [ "?" "?" "?" ] >>> res = df.get_column("baz", default=None) >>> res is None True
- get_column_index(name: str) int[source]
按名称查找列的索引。
- Parameters:
- name
要查找的列的名称。
示例
>>> df = pl.DataFrame( ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} ... ) >>> df.get_column_index("ham") 2 >>> df.get_column_index("sandwich") ColumnNotFoundError: sandwich
- get_columns() list[Series][source]
将DataFrame作为Series的列表获取。
示例
>>> df = pl.DataFrame({"foo": [1, 2, 3], "bar": [4, 5, 6]}) >>> df.get_columns() [shape: (3,) Series: 'foo' [i64] [ 1 2 3 ], shape: (3,) Series: 'bar' [i64] [ 4 5 6 ]]
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 4], ... "b": [0.5, 4, 10, 13], ... "c": [True, True, False, True], ... } ... ) >>> df.get_columns() [shape: (4,) Series: 'a' [i64] [ 1 2 3 4 ], shape: (4,) Series: 'b' [f64] [ 0.5 4.0 10.0 13.0 ], shape: (4,) Series: 'c' [bool] [ true true false true ]]
- glimpse( ) str | None[source]
返回DataFrame的密集预览。
格式化显示每列一行,以便宽数据框显示清晰。每行显示列名、数据类型和前几个值。
- Parameters:
- max_items_per_column
每列显示的最大项目数。
- max_colname_length
显示的列名的最大长度;超过此值的值将被截断,并在末尾添加省略号。
- return_as_string
如果为True,将预览作为字符串返回,而不是打印到stdout。
示例
>>> from datetime import date >>> df = pl.DataFrame( ... { ... "a": [1.0, 2.8, 3.0], ... "b": [4, 5, None], ... "c": [True, False, True], ... "d": [None, "b", "c"], ... "e": ["usd", "eur", None], ... "f": [date(2020, 1, 1), date(2021, 1, 2), date(2022, 1, 1)], ... } ... ) >>> df.glimpse() Rows: 3 Columns: 6 $ a <f64> 1.0, 2.8, 3.0 $ b <i64> 4, 5, None $ c <bool> True, False, True $ d <str> None, 'b', 'c' $ e <str> 'usd', 'eur', None $ f <date> 2020-01-01, 2021-01-02, 2022-01-01
- group_by(
- *by: IntoExpr | Iterable[IntoExpr],
- maintain_order: bool = False,
- **named_by: IntoExpr,
开始一个分组操作。
- Parameters:
- *by
用于分组的列。接受表达式输入。字符串被解析为列名。
- maintain_order
确保组的顺序与输入数据一致。 这比默认的分组操作要慢。 将此设置为
True会阻止在流引擎上运行的可能性。注意
在每个组内,行的顺序总是被保留,无论这个参数如何。
- **named_by
用于分组的额外列,指定为关键字参数。 这些列将被重命名为所使用的关键字。
- Returns:
- GroupBy
可用于执行聚合的对象。
示例
按一列分组并调用
agg来计算另一列的分组总和。>>> df = pl.DataFrame( ... { ... "a": ["a", "b", "a", "b", "c"], ... "b": [1, 2, 1, 3, 3], ... "c": [5, 4, 3, 2, 1], ... } ... ) >>> df.group_by("a").agg(pl.col("b").sum()) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ str ┆ i64 │ ╞═════╪═════╡ │ a ┆ 2 │ │ b ┆ 5 │ │ c ┆ 3 │ └─────┴─────┘
设置
maintain_order=True以确保组的顺序与输入一致。>>> df.group_by("a", maintain_order=True).agg(pl.col("c")) shape: (3, 2) ┌─────┬───────────┐ │ a ┆ c │ │ --- ┆ --- │ │ str ┆ list[i64] │ ╞═════╪═══════════╡ │ a ┆ [5, 3] │ │ b ┆ [4, 2] │ │ c ┆ [1] │ └─────┴───────────┘
通过传递列名列表来按多列分组。
>>> df.group_by(["a", "b"]).agg(pl.max("c")) shape: (4, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ a ┆ 1 ┆ 5 │ │ b ┆ 2 ┆ 4 │ │ b ┆ 3 ┆ 2 │ │ c ┆ 3 ┆ 1 │ └─────┴─────┴─────┘
或者使用位置参数以相同的方式按多列分组。 表达式也被接受。
>>> df.group_by("a", pl.col("b") // 2).agg(pl.col("c").mean()) shape: (3, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ f64 │ ╞═════╪═════╪═════╡ │ a ┆ 0 ┆ 4.0 │ │ b ┆ 1 ┆ 3.0 │ │ c ┆ 1 ┆ 1.0 │ └─────┴─────┴─────┘
此方法返回的
GroupBy对象是可迭代的,返回每个组的名称和数据。>>> for name, data in df.group_by("a"): ... print(name) ... print(data) ('a',) shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ a ┆ 1 ┆ 5 │ │ a ┆ 1 ┆ 3 │ └─────┴─────┴─────┘ ('b',) shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ b ┆ 2 ┆ 4 │ │ b ┆ 3 ┆ 2 │ └─────┴─────┴─────┘ ('c',) shape: (1, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ c ┆ 3 ┆ 1 │ └─────┴─────┴─────┘
- group_by_dynamic(
- index_column: IntoExpr,
- *,
- every: str | timedelta,
- period: str | timedelta | None = None,
- offset: str | timedelta | None = None,
- include_boundaries: bool = False,
- closed: ClosedInterval = 'left',
- label: Label = 'left',
- group_by: IntoExpr | Iterable[IntoExpr] | None = None,
- start_by: StartBy = 'window',
基于时间值(或类型为Int32、Int64的索引值)进行分组。
时间窗口被计算并且行被分配到窗口。与普通的分组不同,一行可以是多个组的成员。 默认情况下,窗口看起来像:
[开始, 开始 + 周期)
[开始 + 每次, 开始 + 每次 + 周期)
[开始 + 2*每, 开始 + 2*每 + 周期)
…
其中
start由start_by,offset,every和最早的数据点决定。详情请参见start_by参数描述。警告
索引列必须按升序排序。如果传递了
group_by,则每个组内的索引列必须按升序排序。- Parameters:
- index_column
用于基于时间窗口进行分组的列。 通常为日期/日期时间类型。 此列必须按升序排序(或者,如果指定了
group_by, 则必须在每个组内按升序排序)。在对索引进行动态分组的情况下,dtype 需要是 {Int32, Int64} 之一。请注意,Int32 会暂时转换为 Int64,因此如果性能很重要,请使用 Int64 列。
- every
窗口的间隔
- period
窗口的长度,如果为None,则等于‘every’
- offset
窗口的偏移量,如果
start_by是'datapoint'则不生效。默认为零。- include_boundaries
将窗口的下限和上限添加到“_lower_boundary”和“_upper_boundary”列中。这会影响性能,因为并行化更加困难。
- closed{‘left’, ‘right’, ‘both’, ‘none’}
定义时间间隔的哪些边是闭合的(包含的)。
- label{‘left’, ‘right’, ‘datapoint’}
定义用于窗口的标签:
‘left’: 窗口的下边界
‘right’: 窗口的上边界
‘datapoint’:给定窗口中索引列的第一个值。 如果您不需要标签位于边界之一,请选择此选项以获得最佳性能
- group_by
同时按此列/这些列分组
- start_by{‘window’, ‘datapoint’, ‘monday’, ‘tuesday’, ‘wednesday’, ‘thursday’, ‘friday’, ‘saturday’, ‘sunday’}
确定第一个窗口开始的策略。
‘window’:首先获取最早的时间戳,使用
every进行截断,然后添加offset。 请注意,每周的窗口从周一开始。‘datapoint’: 从遇到的第一个数据点开始。
一周中的某一天(仅在
every包含'w'时生效):‘monday’: 在第一个数据点之前的星期一开始窗口。
‘tuesday’: 在第一个数据点之前的星期二开始窗口。
…
‘sunday’: 在第一个数据点之前的星期日开始窗口。
然后将结果窗口向后移动,直到最早的数据点位于其中或在其前面。
- Returns:
- DynamicGroupBy
你可以调用
.agg来按组进行聚合的对象,其结果将按index_column排序(但请注意,如果传递了group_by列,它只会在每个组内排序)。
另请参阅
注释
如果你来自pandas,那么
# polars df.group_by_dynamic("ts", every="1d").agg(pl.col("value").sum())
等同于
# pandas df.set_index("ts").resample("D")["value"].sum().reset_index()
尽管请注意,与pandas不同,polars不会为空的窗口添加额外的行。如果你需要
index_column均匀分布,请结合使用DataFrame.upsample()。every、period和offset参数是使用以下字符串语言创建的:1纳秒 (1 纳秒)
1微秒 (1 微秒)
1毫秒 (1 毫秒)
1秒 (1 秒)
1分钟 (1 minute)
1小时 (1小时)
1d (1个日历日)
1w (1个日历周)
1个月 (1个日历月)
1q (1个日历季度)
1年 (1个日历年)
1i (1 索引计数)
或者将它们组合起来: “3d12h4m25s” # 3天,12小时,4分钟,25秒
“日历日”指的是第二天的相应时间(由于夏令时,可能不是24小时)。同样适用于“日历周”、“日历月”、“日历季度”和“日历年”。
在对整数列进行group_by_dynamic操作时,窗口由以下定义:
“1i” # 长度 1
“10i” # 长度 10
示例
>>> from datetime import datetime >>> df = pl.DataFrame( ... { ... "time": pl.datetime_range( ... start=datetime(2021, 12, 16), ... end=datetime(2021, 12, 16, 3), ... interval="30m", ... eager=True, ... ), ... "n": range(7), ... } ... ) >>> df shape: (7, 2) ┌─────────────────────┬─────┐ │ time ┆ n │ │ --- ┆ --- │ │ datetime[μs] ┆ i64 │ ╞═════════════════════╪═════╡ │ 2021-12-16 00:00:00 ┆ 0 │ │ 2021-12-16 00:30:00 ┆ 1 │ │ 2021-12-16 01:00:00 ┆ 2 │ │ 2021-12-16 01:30:00 ┆ 3 │ │ 2021-12-16 02:00:00 ┆ 4 │ │ 2021-12-16 02:30:00 ┆ 5 │ │ 2021-12-16 03:00:00 ┆ 6 │ └─────────────────────┴─────┘
按1小时的时间窗口进行分组。
>>> df.group_by_dynamic("time", every="1h", closed="right").agg(pl.col("n")) shape: (4, 2) ┌─────────────────────┬───────────┐ │ time ┆ n │ │ --- ┆ --- │ │ datetime[μs] ┆ list[i64] │ ╞═════════════════════╪═══════════╡ │ 2021-12-15 23:00:00 ┆ [0] │ │ 2021-12-16 00:00:00 ┆ [1, 2] │ │ 2021-12-16 01:00:00 ┆ [3, 4] │ │ 2021-12-16 02:00:00 ┆ [5, 6] │ └─────────────────────┴───────────┘
窗口边界也可以添加到聚合结果中
>>> df.group_by_dynamic( ... "time", every="1h", include_boundaries=True, closed="right" ... ).agg(pl.col("n").mean()) shape: (4, 4) ┌─────────────────────┬─────────────────────┬─────────────────────┬─────┐ │ _lower_boundary ┆ _upper_boundary ┆ time ┆ n │ │ --- ┆ --- ┆ --- ┆ --- │ │ datetime[μs] ┆ datetime[μs] ┆ datetime[μs] ┆ f64 │ ╞═════════════════════╪═════════════════════╪═════════════════════╪═════╡ │ 2021-12-15 23:00:00 ┆ 2021-12-16 00:00:00 ┆ 2021-12-15 23:00:00 ┆ 0.0 │ │ 2021-12-16 00:00:00 ┆ 2021-12-16 01:00:00 ┆ 2021-12-16 00:00:00 ┆ 1.5 │ │ 2021-12-16 01:00:00 ┆ 2021-12-16 02:00:00 ┆ 2021-12-16 01:00:00 ┆ 3.5 │ │ 2021-12-16 02:00:00 ┆ 2021-12-16 03:00:00 ┆ 2021-12-16 02:00:00 ┆ 5.5 │ └─────────────────────┴─────────────────────┴─────────────────────┴─────┘
当 closed=”left” 时,窗口不包括区间的右端: [lower_bound, upper_bound)
>>> df.group_by_dynamic("time", every="1h", closed="left").agg(pl.col("n")) shape: (4, 2) ┌─────────────────────┬───────────┐ │ time ┆ n │ │ --- ┆ --- │ │ datetime[μs] ┆ list[i64] │ ╞═════════════════════╪═══════════╡ │ 2021-12-16 00:00:00 ┆ [0, 1] │ │ 2021-12-16 01:00:00 ┆ [2, 3] │ │ 2021-12-16 02:00:00 ┆ [4, 5] │ │ 2021-12-16 03:00:00 ┆ [6] │ └─────────────────────┴───────────┘
当 closed="both" 时,窗口边界的时间值属于2个组。
>>> df.group_by_dynamic("time", every="1h", closed="both").agg(pl.col("n")) shape: (4, 2) ┌─────────────────────┬───────────┐ │ time ┆ n │ │ --- ┆ --- │ │ datetime[μs] ┆ list[i64] │ ╞═════════════════════╪═══════════╡ │ 2021-12-16 00:00:00 ┆ [0, 1, 2] │ │ 2021-12-16 01:00:00 ┆ [2, 3, 4] │ │ 2021-12-16 02:00:00 ┆ [4, 5, 6] │ │ 2021-12-16 03:00:00 ┆ [6] │ └─────────────────────┴───────────┘
动态分组也可以与普通键上的分组结合使用
>>> df = df.with_columns(groups=pl.Series(["a", "a", "a", "b", "b", "a", "a"])) >>> df shape: (7, 3) ┌─────────────────────┬─────┬────────┐ │ time ┆ n ┆ groups │ │ --- ┆ --- ┆ --- │ │ datetime[μs] ┆ i64 ┆ str │ ╞═════════════════════╪═════╪════════╡ │ 2021-12-16 00:00:00 ┆ 0 ┆ a │ │ 2021-12-16 00:30:00 ┆ 1 ┆ a │ │ 2021-12-16 01:00:00 ┆ 2 ┆ a │ │ 2021-12-16 01:30:00 ┆ 3 ┆ b │ │ 2021-12-16 02:00:00 ┆ 4 ┆ b │ │ 2021-12-16 02:30:00 ┆ 5 ┆ a │ │ 2021-12-16 03:00:00 ┆ 6 ┆ a │ └─────────────────────┴─────┴────────┘ >>> df.group_by_dynamic( ... "time", ... every="1h", ... closed="both", ... group_by="groups", ... include_boundaries=True, ... ).agg(pl.col("n")) shape: (6, 5) ┌────────┬─────────────────────┬─────────────────────┬─────────────────────┬───────────┐ │ groups ┆ _lower_boundary ┆ _upper_boundary ┆ time ┆ n │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ datetime[μs] ┆ datetime[μs] ┆ datetime[μs] ┆ list[i64] │ ╞════════╪═════════════════════╪═════════════════════╪═════════════════════╪═══════════╡ │ a ┆ 2021-12-16 00:00:00 ┆ 2021-12-16 01:00:00 ┆ 2021-12-16 00:00:00 ┆ [0, 1, 2] │ │ a ┆ 2021-12-16 01:00:00 ┆ 2021-12-16 02:00:00 ┆ 2021-12-16 01:00:00 ┆ [2] │ │ a ┆ 2021-12-16 02:00:00 ┆ 2021-12-16 03:00:00 ┆ 2021-12-16 02:00:00 ┆ [5, 6] │ │ a ┆ 2021-12-16 03:00:00 ┆ 2021-12-16 04:00:00 ┆ 2021-12-16 03:00:00 ┆ [6] │ │ b ┆ 2021-12-16 01:00:00 ┆ 2021-12-16 02:00:00 ┆ 2021-12-16 01:00:00 ┆ [3, 4] │ │ b ┆ 2021-12-16 02:00:00 ┆ 2021-12-16 03:00:00 ┆ 2021-12-16 02:00:00 ┆ [4] │ └────────┴─────────────────────┴─────────────────────┴─────────────────────┴───────────┘
在索引列上进行动态分组
>>> df = pl.DataFrame( ... { ... "idx": pl.int_range(0, 6, eager=True), ... "A": ["A", "A", "B", "B", "B", "C"], ... } ... ) >>> ( ... df.group_by_dynamic( ... "idx", ... every="2i", ... period="3i", ... include_boundaries=True, ... closed="right", ... ).agg(pl.col("A").alias("A_agg_list")) ... ) shape: (4, 4) ┌─────────────────┬─────────────────┬─────┬─────────────────┐ │ _lower_boundary ┆ _upper_boundary ┆ idx ┆ A_agg_list │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 ┆ list[str] │ ╞═════════════════╪═════════════════╪═════╪═════════════════╡ │ -2 ┆ 1 ┆ -2 ┆ ["A", "A"] │ │ 0 ┆ 3 ┆ 0 ┆ ["A", "B", "B"] │ │ 2 ┆ 5 ┆ 2 ┆ ["B", "B", "C"] │ │ 4 ┆ 7 ┆ 4 ┆ ["C"] │ └─────────────────┴─────────────────┴─────┴─────────────────┘
- hash_rows( ) Series[source]
对此DataFrame中的行进行哈希和组合。
哈希值的类型为
UInt64。- Parameters:
- seed
随机种子参数。默认为0。
- seed_1
随机种子参数。如果未设置,默认为
seed。- seed_2
随机种子参数。如果未设置,默认为
seed。- seed_3
随机种子参数。如果未设置,默认为
seed。
注释
此实现
hash_rows不保证在不同Polars版本之间的结果稳定性。其稳定性仅在单个版本内得到保证。示例
>>> df = pl.DataFrame( ... { ... "foo": [1, None, 3, 4], ... "ham": ["a", "b", None, "d"], ... } ... ) >>> df.hash_rows(seed=42) shape: (4,) Series: '' [u64] [ 10783150408545073287 1438741209321515184 10047419486152048166 2047317070637311557 ]
- head(n: int = 5) DataFrame[source]
获取前
n行。- Parameters:
- n
返回的行数。如果传递了负值,则返回除最后
abs(n)行之外的所有行。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> df.head(3) shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ └─────┴─────┴─────┘
传递一个负值以获取除最后
abs(n)行之外的所有行。>>> df.head(-3) shape: (2, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ └─────┴─────┴─────┘
- property height: int[source]
获取行数。
- Returns:
- int
示例
>>> df = pl.DataFrame({"foo": [1, 2, 3, 4, 5]}) >>> df.height 5
- hstack( ) DataFrame[source]
返回一个新的DataFrame,通过将多个Series水平堆叠来扩展它。
- Parameters:
- columns
要堆叠的系列。
- in_place
就地修改。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> x = pl.Series("apple", [10, 20, 30]) >>> df.hstack([x]) shape: (3, 4) ┌─────┬─────┬─────┬───────┐ │ foo ┆ bar ┆ ham ┆ apple │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str ┆ i64 │ ╞═════╪═════╪═════╪═══════╡ │ 1 ┆ 6 ┆ a ┆ 10 │ │ 2 ┆ 7 ┆ b ┆ 20 │ │ 3 ┆ 8 ┆ c ┆ 30 │ └─────┴─────┴─────┴───────┘
- insert_column(index: int, column: IntoExprColumn) DataFrame[source]
在某个列索引处插入一个Series。
此操作是就地进行的。
- Parameters:
- index
插入新列的索引位置。
- column
Series或要插入的表达式。
示例
>>> df = pl.DataFrame({"foo": [1, 2, 3], "bar": [4, 5, 6]}) >>> s = pl.Series("baz", [97, 98, 99]) >>> df.insert_column(1, s) shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ baz ┆ bar │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 1 ┆ 97 ┆ 4 │ │ 2 ┆ 98 ┆ 5 │ │ 3 ┆ 99 ┆ 6 │ └─────┴─────┴─────┘
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 4], ... "b": [0.5, 4, 10, 13], ... "c": [True, True, False, True], ... } ... ) >>> s = pl.Series("d", [-2.5, 15, 20.5, 0]) >>> df.insert_column(3, s) shape: (4, 4) ┌─────┬──────┬───────┬──────┐ │ a ┆ b ┆ c ┆ d │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ bool ┆ f64 │ ╞═════╪══════╪═══════╪══════╡ │ 1 ┆ 0.5 ┆ true ┆ -2.5 │ │ 2 ┆ 4.0 ┆ true ┆ 15.0 │ │ 3 ┆ 10.0 ┆ false ┆ 20.5 │ │ 4 ┆ 13.0 ┆ true ┆ 0.0 │ └─────┴──────┴───────┴──────┘
- interpolate() DataFrame[source]
插值中间值。插值方法是线性的。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, None, 9, 10], ... "bar": [6, 7, 9, None], ... "baz": [1, None, None, 9], ... } ... ) >>> df.interpolate() shape: (4, 3) ┌──────┬──────┬──────────┐ │ foo ┆ bar ┆ baz │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ f64 │ ╞══════╪══════╪══════════╡ │ 1.0 ┆ 6.0 ┆ 1.0 │ │ 5.0 ┆ 7.0 ┆ 3.666667 │ │ 9.0 ┆ 9.0 ┆ 6.333333 │ │ 10.0 ┆ null ┆ 9.0 │ └──────┴──────┴──────────┘
- is_duplicated() Series[source]
获取此DataFrame中所有重复行的掩码。
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 1], ... "b": ["x", "y", "z", "x"], ... } ... ) >>> df.is_duplicated() shape: (4,) Series: '' [bool] [ true false false true ]
此掩码可用于可视化重复的行,如下所示:
>>> df.filter(df.is_duplicated()) shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ str │ ╞═════╪═════╡ │ 1 ┆ x │ │ 1 ┆ x │ └─────┴─────┘
- is_empty() bool[source]
如果DataFrame不包含任何行,则返回
True。示例
>>> df = pl.DataFrame({"foo": [1, 2, 3], "bar": [4, 5, 6]}) >>> df.is_empty() False >>> df.filter(pl.col("foo") > 99).is_empty() True
- is_unique() Series[source]
获取此DataFrame中所有唯一行的掩码。
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 1], ... "b": ["x", "y", "z", "x"], ... } ... ) >>> df.is_unique() shape: (4,) Series: '' [bool] [ false true true false ]
此掩码可用于可视化独特的线条,如下所示:
>>> df.filter(df.is_unique()) shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ str │ ╞═════╪═════╡ │ 2 ┆ y │ │ 3 ┆ z │ └─────┴─────┘
- item(row: int | None = None, column: int | str | None = None) Any[source]
将DataFrame作为标量返回,或返回给定行/列的元素。
- Parameters:
- row
可选的行的索引。
- column
可选的列索引或名称。
另请参阅
row通过索引或谓词获取单行的值。
注释
如果未提供行/列,这相当于
df[0,0],并检查形状是否为(1,1)。如果提供了行/列,这相当于df[row,col]。示例
>>> df = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}) >>> df.select((pl.col("a") * pl.col("b")).sum()).item() 32 >>> df.item(1, 1) 5 >>> df.item(2, "b") 6
- iter_columns() Iterator[Series][source]
返回此DataFrame列的迭代器。
- Yields:
- Series
注释
考虑是否可以使用
all()代替。 如果可以,它将更高效。示例
>>> df = pl.DataFrame( ... { ... "a": [1, 3, 5], ... "b": [2, 4, 6], ... } ... ) >>> [s.name for s in df.iter_columns()] ['a', 'b']
如果你使用这个来修改数据框的列,例如。
>>> # Do NOT do this >>> pl.DataFrame(column * 2 for column in df.iter_columns()) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 2 ┆ 4 │ │ 6 ┆ 8 │ │ 10 ┆ 12 │ └─────┴─────┘
然后考虑是否可以使用
all()代替:>>> df.select(pl.all() * 2) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 2 ┆ 4 │ │ 6 ┆ 8 │ │ 10 ┆ 12 │ └─────┴─────┘
- iter_rows( ) Iterator[tuple[Any, ...]] | Iterator[dict[str, Any]][source]
返回一个迭代器,用于遍历由Python原生值组成的DataFrame行。
- Parameters:
- named
返回字典而不是元组。字典是列名到行值的映射。这比返回常规元组更昂贵,但允许通过列名访问值。
- buffer_size
确定在迭代数据时内部缓冲的行数;您应该仅在非常特定的情况下修改此值,即当默认值被认为不适合您的访问模式时,因为使用缓冲区的加速效果显著(约2-4倍)。将此值设置为零将禁用行缓冲(不推荐)。
- Returns:
- iterator of tuples (default) or dictionaries (if named) of python row values
警告
行迭代不是最优的,因为底层数据是以列式存储的; 在可能的情况下,优先使用处理列式数据的专用导出/输出方法之一进行导出。
另请参阅
rows将所有帧数据具体化为行的列表(可能非常耗费资源)。
rows_by_key将帧数据具体化为一个键索引的字典。
注释
如果你有
ns精度的时间值,你应该知道Python原生只支持到μs精度;ns精度的值在转换为Python时将被截断为微秒。如果这对你的使用场景很重要,你应该导出为不同的格式(如Arrow或NumPy)。示例
>>> df = pl.DataFrame( ... { ... "a": [1, 3, 5], ... "b": [2, 4, 6], ... } ... ) >>> [row[0] for row in df.iter_rows()] [1, 3, 5] >>> [row["b"] for row in df.iter_rows(named=True)] [2, 4, 6]
- iter_slices(n_rows: int = 10000) Iterator[DataFrame][source]
返回一个不复制底层DataFrame切片的迭代器。
- Parameters:
- n_rows
确定每个DataFrame切片中包含的行数。
另请参阅
iter_rows行迭代器遍历帧数据(不会具体化所有行)。
partition_by分割成多个DataFrames,按组分区。
示例
>>> from datetime import date >>> df = pl.DataFrame( ... data={ ... "a": range(17_500), ... "b": date(2023, 1, 1), ... "c": "klmnoopqrstuvwxyz", ... }, ... schema_overrides={"a": pl.Int32}, ... ) >>> for idx, frame in enumerate(df.iter_slices()): ... print(f"{type(frame).__name__}:[{idx}]:{len(frame)}") DataFrame:[0]:10000 DataFrame:[1]:7500
使用
iter_slices是一种高效的方式来分块迭代 DataFrame 和任何支持的框架导出/转换类型;例如,作为 RecordBatches:>>> for frame in df.iter_slices(n_rows=15_000): ... record_batch = frame.to_arrow().to_batches()[0] ... print(f"{record_batch.schema}\n<< {len(record_batch)}") a: int32 b: date32[day] c: large_string << 15000 a: int32 b: date32[day] c: large_string << 2500
- join(
- other: DataFrame,
- on: str | Expr | Sequence[str | Expr] | None = None,
- how: JoinStrategy = 'inner',
- *,
- left_on: str | Expr | Sequence[str | Expr] | None = None,
- right_on: str | Expr | Sequence[str | Expr] | None = None,
- suffix: str = '_right',
- validate: JoinValidation = 'm:m',
- join_nulls: bool = False,
- coalesce: bool | None = None,
- maintain_order: MaintainOrderJoin | None = None,
以类似SQL的方式连接。
- Parameters:
- other
要连接的DataFrame。
- on
两个DataFrame中连接列的名称。
- how{‘inner’, ‘left’, ‘right’, ‘full’, ‘semi’, ‘anti’, ‘cross’}
连接策略。
- inner
返回在两个表中具有匹配值的行
- left
返回左表中的所有行,以及右表中的匹配行
- right
返回右表中的所有行,以及左表中的匹配行
- full
当左表或右表中有匹配时返回所有行
- cross
返回两个表中行的笛卡尔积
- semi
返回左表中与右表匹配的行。
- anti
返回左表中没有与右表匹配的行。
- left_on
左连接列的名称。
- right_on
右连接列的名称。
- suffix
为具有重复名称的列附加的后缀。
- validate: {‘m:m’, ‘m:1’, ‘1:m’, ‘1:1’}
检查连接是否为指定类型。
- many_to_many
“m:m”:默认情况下,不会导致检查
- one_to_one
“1:1”:检查连接键在左右数据集中是否唯一
- one_to_many
“1:m”:检查连接键在左侧数据集中是否唯一
- many_to_one
“m:1”:检查连接键在右侧数据集中是否唯一
注意
目前流式引擎不支持此功能。
- join_nulls
在空值上进行连接。默认情况下,空值永远不会产生匹配。
- coalesce
合并行为(连接列的合并)。
无: -> 加入特定。
True: -> 始终合并连接列。
False: -> 从不合并连接列。
注意
在除了
col之外的任何其他表达式上进行连接将关闭合并。- maintain_order{‘none’, ‘left’, ‘right’, ‘left_right’, ‘right_left’}
保留哪个DataFrame的行顺序(如果有的话)。 如果没有明确设置此参数,请不要依赖任何观察到的顺序,因为您的代码可能会在未来的版本中中断。 不指定任何顺序可以提高性能 支持内连接、左连接、右连接和全连接
- none
不需要特定的排序。排序可能会在不同的Polars版本之间甚至在不同的运行之间有所不同。
- left
保留左侧DataFrame的顺序。
- right
保留右侧DataFrame的顺序。
- left_right
首先保留左侧DataFrame的顺序,然后是右侧。
- right_left
首先保留右侧DataFrame的顺序,然后是左侧。
另请参阅
注释
对于连接具有分类数据的列,请参见
polars.StringCache。示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": ["a", "b", "c"], ... } ... ) >>> other_df = pl.DataFrame( ... { ... "apple": ["x", "y", "z"], ... "ham": ["a", "b", "d"], ... } ... ) >>> df.join(other_df, on="ham") shape: (2, 4) ┌─────┬─────┬─────┬───────┐ │ foo ┆ bar ┆ ham ┆ apple │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str ┆ str │ ╞═════╪═════╪═════╪═══════╡ │ 1 ┆ 6.0 ┆ a ┆ x │ │ 2 ┆ 7.0 ┆ b ┆ y │ └─────┴─────┴─────┴───────┘
>>> df.join(other_df, on="ham", how="full") shape: (4, 5) ┌──────┬──────┬──────┬───────┬───────────┐ │ foo ┆ bar ┆ ham ┆ apple ┆ ham_right │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str ┆ str ┆ str │ ╞══════╪══════╪══════╪═══════╪═══════════╡ │ 1 ┆ 6.0 ┆ a ┆ x ┆ a │ │ 2 ┆ 7.0 ┆ b ┆ y ┆ b │ │ null ┆ null ┆ null ┆ z ┆ d │ │ 3 ┆ 8.0 ┆ c ┆ null ┆ null │ └──────┴──────┴──────┴───────┴───────────┘
>>> df.join(other_df, on="ham", how="left", coalesce=True) shape: (3, 4) ┌─────┬─────┬─────┬───────┐ │ foo ┆ bar ┆ ham ┆ apple │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str ┆ str │ ╞═════╪═════╪═════╪═══════╡ │ 1 ┆ 6.0 ┆ a ┆ x │ │ 2 ┆ 7.0 ┆ b ┆ y │ │ 3 ┆ 8.0 ┆ c ┆ null │ └─────┴─────┴─────┴───────┘
>>> df.join(other_df, on="ham", how="semi") shape: (2, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6.0 ┆ a │ │ 2 ┆ 7.0 ┆ b │ └─────┴─────┴─────┘
>>> df.join(other_df, on="ham", how="anti") shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str │ ╞═════╪═════╪═════╡ │ 3 ┆ 8.0 ┆ c │ └─────┴─────┴─────┘
- join_asof(
- other: DataFrame,
- *,
- left_on: str | None | Expr = None,
- right_on: str | None | Expr = None,
- on: str | None | Expr = None,
- by_left: str | Sequence[str] | None = None,
- by_right: str | Sequence[str] | None = None,
- by: str | Sequence[str] | None = None,
- strategy: AsofJoinStrategy = 'backward',
- suffix: str = '_right',
- tolerance: str | int | float | timedelta | None = None,
- allow_parallel: bool = True,
- force_parallel: bool = False,
- coalesce: bool = True,
执行一个asof连接。
这与左连接类似,不同之处在于我们匹配的是最接近的键而不是相等的键。
两个DataFrame必须按照
on键排序(如果指定了by组,则在每个组内排序)。对于左侧DataFrame中的每一行:
“向后”搜索选择右侧DataFrame中‘on’键小于或等于左侧键的最后一行。
“前向”搜索选择右侧DataFrame中‘on’键大于或等于左侧键的第一行。
“最近”搜索选择右侧DataFrame中值最接近左侧键的最后一行。目前不支持对字符串键进行最近搜索。
默认是“backward”。
- Parameters:
- other
要连接的惰性DataFrame。
- left_on
左侧DataFrame的连接列。
- right_on
右侧DataFrame的连接列。
- on
两个DataFrame的连接列。如果设置了,
left_on和right_on应为 None。- by
在进行asof连接之前,先在这些列上进行连接
- by_left
在进行asof连接之前,先在这些列上进行连接
- by_right
在进行asof连接之前,先在这些列上进行连接
- strategy{‘backward’, ‘forward’, ‘nearest’}
连接策略。
- suffix
为具有重复名称的列附加的后缀。
- tolerance
数值容差。通过设置此值,只有当接近的键在此距离内时才会进行连接。如果在类型为“Date”、“Datetime”、“Duration”或“Time”的列上进行asof连接,请使用datetime.timedelta对象或以下字符串语言:
1纳秒 (1 纳秒)
1微秒 (1 微秒)
1毫秒 (1 毫秒)
1秒 (1 秒)
1分钟 (1 minute)
1小时 (1小时)
1d (1个日历日)
1w (1个日历周)
1个月 (1个日历月)
1q (1个日历季度)
1年 (1个日历年)
或者将它们组合起来: “3d12h4m25s” # 3天,12小时,4分钟,25秒
“日历日”指的是第二天的相应时间(由于夏令时,可能不是24小时)。同样适用于“日历周”、“日历月”、“日历季度”和“日历年”。
- allow_parallel
允许物理计划选择性地并行评估两个DataFrames直到连接的计算。
- force_parallel
强制物理计划并行评估两个DataFrames的计算,直到连接操作。
- coalesce
合并行为(合并
on/left_on/right_on列):True: -> 始终合并连接列。
False: -> 从不合并连接列。
请注意,在
col以外的任何其他表达式上进行连接将关闭合并。
示例
>>> from datetime import date >>> gdp = pl.DataFrame( ... { ... "date": pl.date_range( ... date(2016, 1, 1), ... date(2020, 1, 1), ... "1y", ... eager=True, ... ), ... "gdp": [4164, 4411, 4566, 4696, 4827], ... } ... ) >>> gdp shape: (5, 2) ┌────────────┬──────┐ │ date ┆ gdp │ │ --- ┆ --- │ │ date ┆ i64 │ ╞════════════╪══════╡ │ 2016-01-01 ┆ 4164 │ │ 2017-01-01 ┆ 4411 │ │ 2018-01-01 ┆ 4566 │ │ 2019-01-01 ┆ 4696 │ │ 2020-01-01 ┆ 4827 │ └────────────┴──────┘
>>> population = pl.DataFrame( ... { ... "date": [date(2016, 3, 1), date(2018, 8, 1), date(2019, 1, 1)], ... "population": [82.19, 82.66, 83.12], ... } ... ).sort("date") >>> population shape: (3, 2) ┌────────────┬────────────┐ │ date ┆ population │ │ --- ┆ --- │ │ date ┆ f64 │ ╞════════════╪════════════╡ │ 2016-03-01 ┆ 82.19 │ │ 2018-08-01 ┆ 82.66 │ │ 2019-01-01 ┆ 83.12 │ └────────────┴────────────┘
注意日期并不完全匹配。如果我们使用
join_asof和strategy='backward'进行连接,那么population中没有完全匹配的每个日期将与gdp中最接近的较早日期匹配:>>> population.join_asof(gdp, on="date", strategy="backward") shape: (3, 3) ┌────────────┬────────────┬──────┐ │ date ┆ population ┆ gdp │ │ --- ┆ --- ┆ --- │ │ date ┆ f64 ┆ i64 │ ╞════════════╪════════════╪══════╡ │ 2016-03-01 ┆ 82.19 ┆ 4164 │ │ 2018-08-01 ┆ 82.66 ┆ 4566 │ │ 2019-01-01 ┆ 83.12 ┆ 4696 │ └────────────┴────────────┴──────┘
注意以下几点:
日期
2016-03-01来自population与2016-01-01来自gdp相匹配;日期
2018-08-01来自population与2018-01-01来自gdp相匹配。
你可以通过传递
coalesce=False来验证这一点:>>> population.join_asof(gdp, on="date", strategy="backward", coalesce=False) shape: (3, 4) ┌────────────┬────────────┬────────────┬──────┐ │ date ┆ population ┆ date_right ┆ gdp │ │ --- ┆ --- ┆ --- ┆ --- │ │ date ┆ f64 ┆ date ┆ i64 │ ╞════════════╪════════════╪════════════╪══════╡ │ 2016-03-01 ┆ 82.19 ┆ 2016-01-01 ┆ 4164 │ │ 2018-08-01 ┆ 82.66 ┆ 2018-01-01 ┆ 4566 │ │ 2019-01-01 ┆ 83.12 ┆ 2019-01-01 ┆ 4696 │ └────────────┴────────────┴────────────┴──────┘
如果我们改为使用
strategy='forward',那么population中没有精确匹配的每个日期将与gdp中最接近的较晚日期匹配:>>> population.join_asof(gdp, on="date", strategy="forward") shape: (3, 3) ┌────────────┬────────────┬──────┐ │ date ┆ population ┆ gdp │ │ --- ┆ --- ┆ --- │ │ date ┆ f64 ┆ i64 │ ╞════════════╪════════════╪══════╡ │ 2016-03-01 ┆ 82.19 ┆ 4411 │ │ 2018-08-01 ┆ 82.66 ┆ 4696 │ │ 2019-01-01 ┆ 83.12 ┆ 4696 │ └────────────┴────────────┴──────┘
注意以下几点:
日期
2016-03-01来自population与2017-01-01来自gdp相匹配;日期
2018-08-01来自population与2019-01-01来自gdp相匹配。
最后,
strategy='nearest'给出了上述两种结果的混合,因为每个来自population的日期如果没有精确匹配,则会与来自gdp的最接近日期匹配,无论它是早还是晚:>>> population.join_asof(gdp, on="date", strategy="nearest") shape: (3, 3) ┌────────────┬────────────┬──────┐ │ date ┆ population ┆ gdp │ │ --- ┆ --- ┆ --- │ │ date ┆ f64 ┆ i64 │ ╞════════════╪════════════╪══════╡ │ 2016-03-01 ┆ 82.19 ┆ 4164 │ │ 2018-08-01 ┆ 82.66 ┆ 4696 │ │ 2019-01-01 ┆ 83.12 ┆ 4696 │ └────────────┴────────────┴──────┘
注意以下几点:
日期
2016-03-01来自population与2016-01-01来自gdp相匹配;日期
2018-08-01来自population与2019-01-01来自gdp相匹配。
他们
by参数允许在asof连接之前先连接另一列。 在这个例子中,我们首先通过country连接,然后按日期进行asof连接,如上所述。>>> gdp_dates = pl.date_range( # fmt: skip ... date(2016, 1, 1), date(2020, 1, 1), "1y", eager=True ... ) >>> gdp2 = pl.DataFrame( ... { ... "country": ["Germany"] * 5 + ["Netherlands"] * 5, ... "date": pl.concat([gdp_dates, gdp_dates]), ... "gdp": [4164, 4411, 4566, 4696, 4827, 784, 833, 914, 910, 909], ... } ... ).sort("country", "date") >>> >>> gdp2 shape: (10, 3) ┌─────────────┬────────────┬──────┐ │ country ┆ date ┆ gdp │ │ --- ┆ --- ┆ --- │ │ str ┆ date ┆ i64 │ ╞═════════════╪════════════╪══════╡ │ Germany ┆ 2016-01-01 ┆ 4164 │ │ Germany ┆ 2017-01-01 ┆ 4411 │ │ Germany ┆ 2018-01-01 ┆ 4566 │ │ Germany ┆ 2019-01-01 ┆ 4696 │ │ Germany ┆ 2020-01-01 ┆ 4827 │ │ Netherlands ┆ 2016-01-01 ┆ 784 │ │ Netherlands ┆ 2017-01-01 ┆ 833 │ │ Netherlands ┆ 2018-01-01 ┆ 914 │ │ Netherlands ┆ 2019-01-01 ┆ 910 │ │ Netherlands ┆ 2020-01-01 ┆ 909 │ └─────────────┴────────────┴──────┘ >>> pop2 = pl.DataFrame( ... { ... "country": ["Germany"] * 3 + ["Netherlands"] * 3, ... "date": [ ... date(2016, 3, 1), ... date(2018, 8, 1), ... date(2019, 1, 1), ... date(2016, 3, 1), ... date(2018, 8, 1), ... date(2019, 1, 1), ... ], ... "population": [82.19, 82.66, 83.12, 17.11, 17.32, 17.40], ... } ... ).sort("country", "date") >>> >>> pop2 shape: (6, 3) ┌─────────────┬────────────┬────────────┐ │ country ┆ date ┆ population │ │ --- ┆ --- ┆ --- │ │ str ┆ date ┆ f64 │ ╞═════════════╪════════════╪════════════╡ │ Germany ┆ 2016-03-01 ┆ 82.19 │ │ Germany ┆ 2018-08-01 ┆ 82.66 │ │ Germany ┆ 2019-01-01 ┆ 83.12 │ │ Netherlands ┆ 2016-03-01 ┆ 17.11 │ │ Netherlands ┆ 2018-08-01 ┆ 17.32 │ │ Netherlands ┆ 2019-01-01 ┆ 17.4 │ └─────────────┴────────────┴────────────┘ >>> pop2.join_asof(gdp2, by="country", on="date", strategy="nearest") shape: (6, 4) ┌─────────────┬────────────┬────────────┬──────┐ │ country ┆ date ┆ population ┆ gdp │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ date ┆ f64 ┆ i64 │ ╞═════════════╪════════════╪════════════╪══════╡ │ Germany ┆ 2016-03-01 ┆ 82.19 ┆ 4164 │ │ Germany ┆ 2018-08-01 ┆ 82.66 ┆ 4696 │ │ Germany ┆ 2019-01-01 ┆ 83.12 ┆ 4696 │ │ Netherlands ┆ 2016-03-01 ┆ 17.11 ┆ 784 │ │ Netherlands ┆ 2018-08-01 ┆ 17.32 ┆ 910 │ │ Netherlands ┆ 2019-01-01 ┆ 17.4 ┆ 910 │ └─────────────┴────────────┴────────────┴──────┘
- join_where(
- other: DataFrame,
- *predicates: Expr | Iterable[Expr],
- suffix: str = '_right',
基于一个或多个(不)等式谓词执行连接。
这执行了一个内连接,因此只有所有谓词都为真的行才会包含在结果中,并且来自任一DataFrame的行可能会在结果中出现多次。
注意
输入DataFrames的行顺序不会被保留。
警告
此功能是实验性的。它可能会在任何时候更改,而不被视为破坏性更改。
- Parameters:
- other
要连接的DataFrame。
- *predicates
用于连接两个表的(不)等式条件。 当一个列名在两个表中都出现时,必须在谓词中应用适当的后缀。
- suffix
为具有重复名称的列附加的后缀。
示例
>>> east = pl.DataFrame( ... { ... "id": [100, 101, 102], ... "dur": [120, 140, 160], ... "rev": [12, 14, 16], ... "cores": [2, 8, 4], ... } ... ) >>> west = pl.DataFrame( ... { ... "t_id": [404, 498, 676, 742], ... "time": [90, 130, 150, 170], ... "cost": [9, 13, 15, 16], ... "cores": [4, 2, 1, 4], ... } ... ) >>> east.join_where( ... west, ... pl.col("dur") < pl.col("time"), ... pl.col("rev") < pl.col("cost"), ... ) shape: (5, 8) ┌─────┬─────┬─────┬───────┬──────┬──────┬──────┬─────────────┐ │ id ┆ dur ┆ rev ┆ cores ┆ t_id ┆ time ┆ cost ┆ cores_right │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╪═══════╪══════╪══════╪══════╪═════════════╡ │ 100 ┆ 120 ┆ 12 ┆ 2 ┆ 498 ┆ 130 ┆ 13 ┆ 2 │ │ 100 ┆ 120 ┆ 12 ┆ 2 ┆ 676 ┆ 150 ┆ 15 ┆ 1 │ │ 100 ┆ 120 ┆ 12 ┆ 2 ┆ 742 ┆ 170 ┆ 16 ┆ 4 │ │ 101 ┆ 140 ┆ 14 ┆ 8 ┆ 676 ┆ 150 ┆ 15 ┆ 1 │ │ 101 ┆ 140 ┆ 14 ┆ 8 ┆ 742 ┆ 170 ┆ 16 ┆ 4 │ └─────┴─────┴─────┴───────┴──────┴──────┴──────┴─────────────┘
- lazy() LazyFrame[source]
从这一点开始一个惰性查询。这将返回一个
LazyFrame对象。在
LazyFrame上的操作直到通过调用以下之一触发时才会执行:.collect()(在所有数据上运行)
.explain()(打印查询计划)
.show_graph()(将查询计划显示为graphviz图)
.collect_schema()(返回最终的框架模式)
建议使用惰性操作,因为它们允许查询优化和额外的并行性。
- Returns:
- LazyFrame
示例
>>> df = pl.DataFrame( ... { ... "a": [None, 2, 3, 4], ... "b": [0.5, None, 2.5, 13], ... "c": [True, True, False, None], ... } ... ) >>> df.lazy() <LazyFrame at ...>
- limit(n: int = 5) DataFrame[source]
获取前
n行。DataFrame.head()的别名。- Parameters:
- n
返回的行数。如果传递了负值,则返回除最后
abs(n)行之外的所有行。
另请参阅
示例
获取DataFrame的前3行。
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> df.limit(3) shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ └─────┴─────┴─────┘
- map_rows(
- function: Callable[[tuple[Any, ...]], Any],
- return_dtype: PolarsDataType | None = None,
- *,
- inference_size: int = 256,
在DataFrame的行上应用自定义/用户定义的函数(UDF)。
警告
此方法比原生表达式API慢得多。 只有在无法以其他方式实现逻辑时才使用它。
UDF将接收每一行作为值的元组:
udf(row)。使用Python函数实现逻辑几乎总是比使用原生表达式API实现相同逻辑显著更慢且更占用内存,因为:
原生表达式引擎在Rust中运行;UDFs在Python中运行。
使用Python UDFs会强制将DataFrame物化在内存中。
Polars原生表达式可以并行化(UDF通常不能)。
Polars原生表达式可以进行逻辑优化(UDF则不能)。
在可能的情况下,您应该强烈倾向于使用原生表达式API以实现最佳性能。
- Parameters:
- function
自定义函数或lambda。
- return_dtype
操作的输出类型。如果未给出,Polars 会尝试推断类型。
- inference_size
仅在自定义函数返回行的情况下使用。 这使用前
n行来确定输出模式。
注释
框架级别的
map_rows无法跟踪列名(因为UDF是一个黑盒,可能会任意删除、重新排列、转换或添加新列);如果你想应用一个UDF以保留列名,你应该使用表达式级别的map_elements语法。如果你的函数计算成本高,并且你不希望它在给定输入时被多次调用,考虑对其应用
@lru_cache装饰器。如果你的数据适合,你可能会实现显著的加速。
示例
>>> df = pl.DataFrame({"foo": [1, 2, 3], "bar": [-1, 5, 8]})
通过将每一行映射到一个元组来返回一个DataFrame:
>>> df.map_rows(lambda t: (t[0] * 2, t[1] * 3)) shape: (3, 2) ┌──────────┬──────────┐ │ column_0 ┆ column_1 │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞══════════╪══════════╡ │ 2 ┆ -3 │ │ 4 ┆ 15 │ │ 6 ┆ 24 │ └──────────┴──────────┘
然而,使用原生表达式实现这一点要好得多:
>>> df.select( ... pl.col("foo") * 2, ... pl.col("bar") * 3, ... )
通过将每一行映射到一个标量来返回一个单列的DataFrame:
>>> df.map_rows(lambda t: (t[0] * 2 + t[1])) shape: (3, 1) ┌─────┐ │ map │ │ --- │ │ i64 │ ╞═════╡ │ 1 │ │ 9 │ │ 14 │ └─────┘
在这种情况下,最好使用以下原生表达式:
>>> df.select(pl.col("foo") * 2 + pl.col("bar"))
- max() DataFrame[source]
将此DataFrame的列聚合到它们的最大值。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.max() shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 3 ┆ 8 ┆ c │ └─────┴─────┴─────┘
- max_horizontal() Series[source]
获取列之间的水平最大值。
- Returns:
- Series
一个名为
"max"的 Series。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [4.0, 5.0, 6.0], ... } ... ) >>> df.max_horizontal() shape: (3,) Series: 'max' [f64] [ 4.0 5.0 6.0 ]
- mean() DataFrame[source]
将此DataFrame的列聚合为其平均值。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... "spam": [True, False, None], ... } ... ) >>> df.mean() shape: (1, 4) ┌─────┬─────┬──────┬──────┐ │ foo ┆ bar ┆ ham ┆ spam │ │ --- ┆ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str ┆ f64 │ ╞═════╪═════╪══════╪══════╡ │ 2.0 ┆ 7.0 ┆ null ┆ 0.5 │ └─────┴─────┴──────┴──────┘
- mean_horizontal(*, ignore_nulls: bool = True) Series[source]
取所有值在列之间的水平平均值。
- Parameters:
- ignore_nulls
忽略空值(默认)。 如果设置为
False,输入中的任何空值将导致输出为空。
- Returns:
- Series
一个名为
"mean"的 Series。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [4.0, 5.0, 6.0], ... } ... ) >>> df.mean_horizontal() shape: (3,) Series: 'mean' [f64] [ 2.5 3.5 4.5 ]
- median() DataFrame[source]
将此DataFrame的列聚合到它们的中值。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.median() shape: (1, 3) ┌─────┬─────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str │ ╞═════╪═════╪══════╡ │ 2.0 ┆ 7.0 ┆ null │ └─────┴─────┴──────┘
- melt(
- id_vars: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None,
- value_vars: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None,
- variable_name: str | None = None,
- value_name: str | None = None,
将DataFrame从宽格式转换为长格式。
可选地保留标识符设置。
此函数有助于将DataFrame整理成一种格式,其中一列或多列是标识变量(id_vars),而所有其他列,被视为测量变量(value_vars),被“逆透视”到行轴,只留下两个非标识列,‘variable’和‘value’。
自版本1.0.0起已弃用:请改用
unpivot()。- Parameters:
- id_vars
用作标识符变量的列或选择器。
- value_vars
用作值变量的列或选择器;如果
value_vars为空,则所有不在id_vars中的列将被使用。- variable_name
为
variable列指定的名称。默认为“variable”- value_name
为
value列指定的名称。默认为“value”
- merge_sorted(
- other: DataFrame,
- key: str,
取两个已排序的DataFrame并按排序键合并它们。
此操作的输出也将被排序。 调用者有责任确保帧按该键排序,否则输出将没有意义。
两个DataFrame的模式必须相同。
- Parameters:
- other
必须合并的其他DataFrame
- key
被排序的键。
示例
>>> df0 = pl.DataFrame( ... {"name": ["steve", "elise", "bob"], "age": [42, 44, 18]} ... ).sort("age") >>> df0 shape: (3, 2) ┌───────┬─────┐ │ name ┆ age │ │ --- ┆ --- │ │ str ┆ i64 │ ╞═══════╪═════╡ │ bob ┆ 18 │ │ steve ┆ 42 │ │ elise ┆ 44 │ └───────┴─────┘ >>> df1 = pl.DataFrame( ... {"name": ["anna", "megan", "steve", "thomas"], "age": [21, 33, 42, 20]} ... ).sort("age") >>> df1 shape: (4, 2) ┌────────┬─────┐ │ name ┆ age │ │ --- ┆ --- │ │ str ┆ i64 │ ╞════════╪═════╡ │ thomas ┆ 20 │ │ anna ┆ 21 │ │ megan ┆ 33 │ │ steve ┆ 42 │ └────────┴─────┘ >>> df0.merge_sorted(df1, key="age") shape: (7, 2) ┌────────┬─────┐ │ name ┆ age │ │ --- ┆ --- │ │ str ┆ i64 │ ╞════════╪═════╡ │ bob ┆ 18 │ │ thomas ┆ 20 │ │ anna ┆ 21 │ │ megan ┆ 33 │ │ steve ┆ 42 │ │ steve ┆ 42 │ │ elise ┆ 44 │ └────────┴─────┘
- min() DataFrame[source]
将此DataFrame的列聚合到它们的最小值。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.min() shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ └─────┴─────┴─────┘
- min_horizontal() Series[source]
获取列之间的水平最小值。
- Returns:
- Series
一个名为
"min"的 Series。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [4.0, 5.0, 6.0], ... } ... ) >>> df.min_horizontal() shape: (3,) Series: 'min' [f64] [ 1.0 2.0 3.0 ]
- n_chunks(strategy: Literal['first', 'all'] = 'first') int | list[int][source]
获取此DataFrame的ChunkedArrays使用的块数。
- Parameters:
- strategy{‘first’, ‘all’}
返回此DataFrame中‘first’列或‘all’列的分块数量。
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 4], ... "b": [0.5, 4, 10, 13], ... "c": [True, True, False, True], ... } ... ) >>> df.n_chunks() 1 >>> df.n_chunks(strategy="all") [1, 1, 1]
- n_unique(subset: str | Expr | Sequence[str | Expr] | None = None) int[source]
返回唯一行的数量,或唯一行子集的数量。
- Parameters:
- subset
定义一个或多个列/表达式以确定计数的内容;省略则返回唯一行的计数。
注释
此方法在
DataFrame级别操作;要在表达式级别对子集进行操作,可以使用结构打包,例如:>>> expr_unique_subset = pl.struct("a", "b").n_unique()
如果你想要计算每列的唯一值的数量,你也可以使用表达式级别的语法来返回包含该结果的新框架:
>>> df = pl.DataFrame( ... [[1, 2, 3], [1, 2, 4]], schema=["a", "b", "c"], orient="row" ... ) >>> df_nunique = df.select(pl.all().n_unique())
在聚合上下文中,还有一个等效的方法用于返回每个组的唯一值:
>>> df_agg_nunique = df.group_by("a").n_unique()
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 1, 2, 3, 4, 5], ... "b": [0.5, 0.5, 1.0, 2.0, 3.0, 3.0], ... "c": [True, True, True, False, True, True], ... } ... ) >>> df.n_unique() 5
简单的列子集。
>>> df.n_unique(subset=["b", "c"]) 4
表达式子集。
>>> df.n_unique( ... subset=[ ... (pl.col("a") // 2), ... (pl.col("c") | (pl.col("b") >= 2)), ... ], ... ) 3
- null_count() DataFrame[source]
创建一个新的DataFrame,显示每列的空值计数。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, None, 3], ... "bar": [6, 7, None], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.null_count() shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ u32 ┆ u32 ┆ u32 │ ╞═════╪═════╪═════╡ │ 1 ┆ 1 ┆ 0 │ └─────┴─────┴─────┘
- partition_by(
- by: ColumnNameOrSelector | Sequence[ColumnNameOrSelector],
- *more_by: ColumnNameOrSelector,
- maintain_order: bool = True,
- include_key: bool = True,
- as_dict: bool = False,
按给定的列进行分组,并将分组作为单独的数据框返回。
- Parameters:
- by
要分组的列名或选择器。
- *more_by
用于分组的额外列名,指定为位置参数。
- maintain_order
确保组的顺序与输入数据一致。 这比默认的分区操作要慢。
- include_key
在输出中包含用于分区DataFrame的列。
- as_dict
返回一个字典而不是列表。字典的键是标识每个组的不同组值的元组。
示例
传递单个列名以按该列进行分区。
>>> df = pl.DataFrame( ... { ... "a": ["a", "b", "a", "b", "c"], ... "b": [1, 2, 1, 3, 3], ... "c": [5, 4, 3, 2, 1], ... } ... ) >>> df.partition_by("a") [shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ a ┆ 1 ┆ 5 │ │ a ┆ 1 ┆ 3 │ └─────┴─────┴─────┘, shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ b ┆ 2 ┆ 4 │ │ b ┆ 3 ┆ 2 │ └─────┴─────┴─────┘, shape: (1, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ c ┆ 3 ┆ 1 │ └─────┴─────┴─────┘]
通过传递列名列表或指定每个列名作为位置参数,按多列进行分区。
>>> df.partition_by("a", "b") [shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ a ┆ 1 ┆ 5 │ │ a ┆ 1 ┆ 3 │ └─────┴─────┴─────┘, shape: (1, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ b ┆ 2 ┆ 4 │ └─────┴─────┴─────┘, shape: (1, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ b ┆ 3 ┆ 2 │ └─────┴─────┴─────┘, shape: (1, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ c ┆ 3 ┆ 1 │ └─────┴─────┴─────┘]
通过指定
as_dict=True将分区作为字典返回。>>> import polars.selectors as cs >>> df.partition_by(cs.string(), as_dict=True) {('a',): shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ a ┆ 1 ┆ 5 │ │ a ┆ 1 ┆ 3 │ └─────┴─────┴─────┘, ('b',): shape: (2, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ b ┆ 2 ┆ 4 │ │ b ┆ 3 ┆ 2 │ └─────┴─────┴─────┘, ('c',): shape: (1, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ c ┆ 3 ┆ 1 │ └─────┴─────┴─────┘}
- pipe(
- function: Callable[Concatenate[DataFrame, P], T],
- *args: P.args,
- **kwargs: P.kwargs,
提供了一种结构化的方式来应用一系列用户定义的函数(UDFs)。
- Parameters:
- function
可调用的;将接收帧作为第一个参数,后面跟随任何给定的args/kwargs。
- *args
传递给UDF的参数。
- **kwargs
传递给UDF的关键字参数。
注释
建议在管道操作时使用LazyFrame,以充分利用查询优化和并行化。参见
df.lazy()。示例
>>> def cast_str_to_int(data, col_name): ... return data.with_columns(pl.col(col_name).cast(pl.Int64)) >>> df = pl.DataFrame({"a": [1, 2, 3, 4], "b": ["10", "20", "30", "40"]}) >>> df.pipe(cast_str_to_int, col_name="b") shape: (4, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 10 │ │ 2 ┆ 20 │ │ 3 ┆ 30 │ │ 4 ┆ 40 │ └─────┴─────┘
>>> df = pl.DataFrame({"b": [1, 2], "a": [3, 4]}) >>> df shape: (2, 2) ┌─────┬─────┐ │ b ┆ a │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 3 │ │ 2 ┆ 4 │ └─────┴─────┘ >>> df.pipe(lambda tdf: tdf.select(sorted(tdf.columns))) shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 3 ┆ 1 │ │ 4 ┆ 2 │ └─────┴─────┘
- pivot(
- on: ColumnNameOrSelector | Sequence[ColumnNameOrSelector],
- *,
- index: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None,
- values: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None,
- aggregate_function: PivotAgg | Expr | None = None,
- maintain_order: bool = True,
- sort_columns: bool = False,
- separator: str = '_',
创建一个电子表格样式的数据透视表作为DataFrame。
仅在急切模式下可用。如果您提前知道唯一的列值,请参阅下面的“示例”部分以了解如何执行“惰性透视”。
- Parameters:
- on
其值将用作输出DataFrame的新列的列。
- index
从输入到输出保留的列。输出DataFrame将为每个
index值的唯一组合生成一行。 如果为None,则所有未在on和values上指定的剩余列将被使用。至少必须指定index和values中的一个。- values
现有的值列将被移动到索引下的新列中。如果指定了聚合,这些是将计算聚合的值。如果为None,则将使用未在
on和index上指定的所有剩余列。必须指定index和values中的至少一个。- aggregate_function
选择以下内容:
无:不进行聚合,如果组中有多个值将引发错误。
预定义的聚合函数字符串,其中之一是 {‘min’, ‘max’, ‘first’, ‘last’, ‘sum’, ‘mean’, ‘median’, ‘len’}
一个用于进行聚合的表达式。
- maintain_order
确保
index的值按发现顺序排序。- sort_columns
按名称对转置的列进行排序。默认是按发现顺序。
- separator
在生成列名时用作分隔符/定界符,以防有多个
values列。
- Returns:
- DataFrame
注释
在其他一些框架中,你可能知道这个操作是
pivot_wider。示例
你可以使用
pivot将数据框从“长”格式重塑为“宽”格式。例如,假设我们有一个由一些学生取得的测试成绩的数据框,其中每一行代表一个不同的测试。
>>> df = pl.DataFrame( ... { ... "name": ["Cady", "Cady", "Karen", "Karen"], ... "subject": ["maths", "physics", "maths", "physics"], ... "test_1": [98, 99, 61, 58], ... "test_2": [100, 100, 60, 60], ... } ... ) >>> df shape: (4, 4) ┌───────┬─────────┬────────┬────────┐ │ name ┆ subject ┆ test_1 ┆ test_2 │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ str ┆ i64 ┆ i64 │ ╞═══════╪═════════╪════════╪════════╡ │ Cady ┆ maths ┆ 98 ┆ 100 │ │ Cady ┆ physics ┆ 99 ┆ 100 │ │ Karen ┆ maths ┆ 61 ┆ 60 │ │ Karen ┆ physics ┆ 58 ┆ 60 │ └───────┴─────────┴────────┴────────┘
使用
pivot,我们可以重塑数据,使每个学生有一行,不同的科目作为列,他们的test_1分数作为值:>>> df.pivot("subject", index="name", values="test_1") shape: (2, 3) ┌───────┬───────┬─────────┐ │ name ┆ maths ┆ physics │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 │ ╞═══════╪═══════╪═════════╡ │ Cady ┆ 98 ┆ 99 │ │ Karen ┆ 61 ┆ 58 │ └───────┴───────┴─────────┘
你也可以使用选择器 - 这里我们在透视表中包含了所有的测试分数:
>>> import polars.selectors as cs >>> df.pivot("subject", values=cs.starts_with("test")) shape: (2, 5) ┌───────┬──────────────┬────────────────┬──────────────┬────────────────┐ │ name ┆ test_1_maths ┆ test_1_physics ┆ test_2_maths ┆ test_2_physics │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 ┆ i64 ┆ i64 │ ╞═══════╪══════════════╪════════════════╪══════════════╪════════════════╡ │ Cady ┆ 98 ┆ 99 ┆ 100 ┆ 100 │ │ Karen ┆ 61 ┆ 58 ┆ 60 ┆ 60 │ └───────┴──────────────┴────────────────┴──────────────┴────────────────┘
如果每个单元格最终有多个值,你可以指定如何用
aggregate_function来聚合它们:>>> df = pl.DataFrame( ... { ... "ix": [1, 1, 2, 2, 1, 2], ... "col": ["a", "a", "a", "a", "b", "b"], ... "foo": [0, 1, 2, 2, 7, 1], ... "bar": [0, 2, 0, 0, 9, 4], ... } ... ) >>> df.pivot("col", index="ix", aggregate_function="sum") shape: (2, 5) ┌─────┬───────┬───────┬───────┬───────┐ │ ix ┆ foo_a ┆ foo_b ┆ bar_a ┆ bar_b │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │ ╞═════╪═══════╪═══════╪═══════╪═══════╡ │ 1 ┆ 1 ┆ 7 ┆ 2 ┆ 9 │ │ 2 ┆ 4 ┆ 1 ┆ 0 ┆ 4 │ └─────┴───────┴───────┴───────┴───────┘
你也可以使用
polars.element()传递一个自定义的聚合函数:>>> df = pl.DataFrame( ... { ... "col1": ["a", "a", "a", "b", "b", "b"], ... "col2": ["x", "x", "x", "x", "y", "y"], ... "col3": [6, 7, 3, 2, 5, 7], ... } ... ) >>> df.pivot( ... "col2", ... index="col1", ... values="col3", ... aggregate_function=pl.element().tanh().mean(), ... ) shape: (2, 3) ┌──────┬──────────┬──────────┐ │ col1 ┆ x ┆ y │ │ --- ┆ --- ┆ --- │ │ str ┆ f64 ┆ f64 │ ╞══════╪══════════╪══════════╡ │ a ┆ 0.998347 ┆ null │ │ b ┆ 0.964028 ┆ 0.999954 │ └──────┴──────────┴──────────┘
请注意,
pivot仅在急切模式下可用。如果您提前知道唯一的列值,可以使用polars.LazyFrame.group_by()在惰性模式下获得与上述相同的结果:>>> index = pl.col("col1") >>> on = pl.col("col2") >>> values = pl.col("col3") >>> unique_column_values = ["x", "y"] >>> aggregate_function = lambda col: col.tanh().mean() >>> df.lazy().group_by(index).agg( ... aggregate_function(values.filter(on == value)).alias(value) ... for value in unique_column_values ... ).collect() shape: (2, 3) ┌──────┬──────────┬──────────┐ │ col1 ┆ x ┆ y │ │ --- ┆ --- ┆ --- │ │ str ┆ f64 ┆ f64 │ ╞══════╪══════════╪══════════╡ │ a ┆ 0.998347 ┆ null │ │ b ┆ 0.964028 ┆ 0.999954 │ └──────┴──────────┴──────────┘
- property plot: DataFramePlot[source]
创建一个绘图命名空间。
警告
此功能目前被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
在版本1.6.0中更改:在Polars的早期版本中,HvPlot是绘图后端。如果您想恢复以前的绘图功能,您只需要在脚本的顶部添加
import hvplot.polars,并将df.plot替换为df.hvplot。Polars 本身不实现绘图逻辑,而是依赖于 Altair:
df.plot.line(**kwargs)是alt.Chart(df).mark_line(tooltip=True).encode(**kwargs).interactive()的简写df.plot.point(**kwargs)是alt.Chart(df).mark_point(tooltip=True).encode(**kwargs).interactive()的简写形式(并且plot.scatter作为别名提供)df.plot.bar(**kwargs)是alt.Chart(df).mark_bar(tooltip=True).encode(**kwargs).interactive()的简写对于任何其他属性
attr,df.plot.attr(**kwargs)是alt.Chart(df).mark_attr(tooltip=True).encode(**kwargs).interactive()的简写
对于配置,我们建议阅读 图表配置。 例如,您可以:
使用
.properties(width=500, height=350, title="My amazing plot")更改宽度/高度/标题。使用
.configure_axisX(labelAngle=30)更改 x 轴标签的旋转角度。通过
.configure_point(opacity=.5)更改散点图中点的透明度。
示例
散点图:
>>> df = pl.DataFrame( ... { ... "length": [1, 4, 6], ... "width": [4, 5, 6], ... "species": ["setosa", "setosa", "versicolor"], ... } ... ) >>> df.plot.point(x="length", y="width", color="species")
通过使用
altair.X设置 x 轴标题:>>> import altair as alt >>> df.plot.point( ... x=alt.X("length", title="Length"), y="width", color="species" ... )
折线图:
>>> from datetime import date >>> df = pl.DataFrame( ... { ... "date": [date(2020, 1, 2), date(2020, 1, 3), date(2020, 1, 4)] * 2, ... "price": [1, 4, 6, 1, 5, 2], ... "stock": ["a", "a", "a", "b", "b", "b"], ... } ... ) >>> df.plot.line(x="date", y="price", color="stock")
条形图:
>>> df = pl.DataFrame( ... { ... "day": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] * 2, ... "group": ["a"] * 7 + ["b"] * 7, ... "value": [1, 3, 2, 4, 5, 6, 1, 1, 3, 2, 4, 5, 1, 2], ... } ... ) >>> df.plot.bar( ... x="day", y="value", color="day", column="group" ... )
或者,制作上述图表的堆叠版本:
>>> df.plot.bar(x="day", y="value", color="group")
- product() DataFrame[source]
将此DataFrame的列聚合为其乘积值。
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3], ... "b": [0.5, 4, 10], ... "c": [True, True, False], ... } ... )
>>> df.product() shape: (1, 3) ┌─────┬──────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ i64 │ ╞═════╪══════╪═════╡ │ 6 ┆ 20.0 ┆ 0 │ └─────┴──────┴─────┘
- quantile(
- quantile: float,
- interpolation: RollingInterpolationMethod = 'nearest',
将此DataFrame的列聚合到它们的分位数值。
- Parameters:
- quantile
分位数在0.0到1.0之间。
- interpolation{‘nearest’, ‘higher’, ‘lower’, ‘midpoint’, ‘linear’}
插值方法。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.quantile(0.5, "nearest") shape: (1, 3) ┌─────┬─────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str │ ╞═════╪═════╪══════╡ │ 2.0 ┆ 7.0 ┆ null │ └─────┴─────┴──────┘
- rechunk() DataFrame[source]
将此DataFrame中的数据重新分块为连续分配。
这将确保所有后续操作具有最佳和可预测的性能。
- rename( ) DataFrame[source]
重命名列名。
- Parameters:
- mapping
从旧名称映射到新名称的键值对,或者一个以旧名称为输入并返回新名称的函数。
- strict
验证当前模式中是否存在所有列名,如果不存在则抛出异常。(请注意,当传递函数给
mapping时,此参数无效)。
示例
>>> df = pl.DataFrame( ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} ... ) >>> df.rename({"foo": "apple"}) shape: (3, 3) ┌───────┬─────┬─────┐ │ apple ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═══════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ └───────┴─────┴─────┘ >>> df.rename(lambda column_name: "c" + column_name[1:]) shape: (3, 3) ┌─────┬─────┬─────┐ │ coo ┆ car ┆ cam │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ └─────┴─────┴─────┘
- replace_column(index: int, column: Series) DataFrame[source]
在索引位置替换一列。
此操作是就地进行的。
- Parameters:
- index
列索引。
- column
将替换列的系列。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> s = pl.Series("apple", [10, 20, 30]) >>> df.replace_column(0, s) shape: (3, 3) ┌───────┬─────┬─────┐ │ apple ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═══════╪═════╪═════╡ │ 10 ┆ 6 ┆ a │ │ 20 ┆ 7 ┆ b │ │ 30 ┆ 8 ┆ c │ └───────┴─────┴─────┘
- reverse() DataFrame[source]
反转DataFrame。
示例
>>> df = pl.DataFrame( ... { ... "key": ["a", "b", "c"], ... "val": [1, 2, 3], ... } ... ) >>> df.reverse() shape: (3, 2) ┌─────┬─────┐ │ key ┆ val │ │ --- ┆ --- │ │ str ┆ i64 │ ╞═════╪═════╡ │ c ┆ 3 │ │ b ┆ 2 │ │ a ┆ 1 │ └─────┴─────┘
- rolling(
- index_column: IntoExpr,
- *,
- period: str | timedelta,
- offset: str | timedelta | None = None,
- closed: ClosedInterval = 'right',
- group_by: IntoExpr | Iterable[IntoExpr] | None = None,
基于时间或整数列创建滚动组。
与
group_by_dynamic不同,窗口现在由各个值决定,而不是固定的间隔。对于固定间隔,请使用DataFrame.group_by_dynamic()。如果你有一个时间序列
,那么默认创建的窗口将是t_1, ..., t_n> (t_0 - 周期, t_0]
(t_1 - 周期, t_1]
…
(t_n - 周期, t_n]
而如果你传递一个非默认的
offset,那么窗口将会是(t_0 + offset, t_0 + offset + period]
(t_1 + offset, t_1 + offset + period]
…
(t_n + offset, t_n + offset + period]
period和offset参数可以通过 timedelta 创建,或者使用以下字符串语言创建:1纳秒 (1 纳秒)
1微秒 (1 微秒)
1毫秒 (1 毫秒)
1秒 (1 秒)
1分钟 (1 minute)
1小时 (1小时)
1d (1个日历日)
1w (1个日历周)
1个月 (1个日历月)
1q (1个日历季度)
1年 (1个日历年)
1i (1 索引计数)
或者将它们组合起来: “3d12h4m25s” # 3天,12小时,4分钟,25秒
“日历日”指的是第二天的相应时间(由于夏令时,可能不是24小时)。同样适用于“日历周”、“日历月”、“日历季度”和“日历年”。
- Parameters:
- index_column
用于基于时间窗口进行分组的列。 通常为日期/日期时间类型。 此列必须按升序排序(或者,如果指定了
group_by,则必须在每个组内按升序排序)。在对索引进行滚动操作时,dtype 需要是以下之一 {UInt32, UInt64, Int32, Int64}。请注意,前三个会暂时 转换为 Int64,因此如果性能很重要,请使用 Int64 列。
- period
窗口的长度 - 必须为非负数。
- offset
窗口的偏移量。默认是
-period。- closed{‘right’, ‘left’, ‘both’, ‘none’}
定义时间间隔的哪些边是闭合的(包含的)。
- group_by
同时按此列/这些列分组
- Returns:
- RollingGroupBy
你可以调用
.agg来按组进行聚合的对象,其结果将按index_column排序(但请注意,如果传递了group_by列,则仅在每个组内排序)。
另请参阅
示例
>>> dates = [ ... "2020-01-01 13:45:48", ... "2020-01-01 16:42:13", ... "2020-01-01 16:45:09", ... "2020-01-02 18:12:48", ... "2020-01-03 19:45:32", ... "2020-01-08 23:16:43", ... ] >>> df = pl.DataFrame({"dt": dates, "a": [3, 7, 5, 9, 2, 1]}).with_columns( ... pl.col("dt").str.strptime(pl.Datetime).set_sorted() ... ) >>> out = df.rolling(index_column="dt", period="2d").agg( ... [ ... pl.sum("a").alias("sum_a"), ... pl.min("a").alias("min_a"), ... pl.max("a").alias("max_a"), ... ] ... ) >>> assert out["sum_a"].to_list() == [3, 10, 15, 24, 11, 1] >>> assert out["max_a"].to_list() == [3, 7, 7, 9, 9, 1] >>> assert out["min_a"].to_list() == [3, 3, 3, 3, 2, 1] >>> out shape: (6, 4) ┌─────────────────────┬───────┬───────┬───────┐ │ dt ┆ sum_a ┆ min_a ┆ max_a │ │ --- ┆ --- ┆ --- ┆ --- │ │ datetime[μs] ┆ i64 ┆ i64 ┆ i64 │ ╞═════════════════════╪═══════╪═══════╪═══════╡ │ 2020-01-01 13:45:48 ┆ 3 ┆ 3 ┆ 3 │ │ 2020-01-01 16:42:13 ┆ 10 ┆ 3 ┆ 7 │ │ 2020-01-01 16:45:09 ┆ 15 ┆ 3 ┆ 7 │ │ 2020-01-02 18:12:48 ┆ 24 ┆ 3 ┆ 9 │ │ 2020-01-03 19:45:32 ┆ 11 ┆ 2 ┆ 9 │ │ 2020-01-08 23:16:43 ┆ 1 ┆ 1 ┆ 1 │ └─────────────────────┴───────┴───────┴───────┘
如果你在
period或offset中使用索引计数,那么它是基于index_column中的值:>>> df = pl.DataFrame({"int": [0, 4, 5, 6, 8], "value": [1, 4, 2, 4, 1]}) >>> df.rolling("int", period="3i").agg(pl.col("int").alias("aggregated")) shape: (5, 2) ┌─────┬────────────┐ │ int ┆ aggregated │ │ --- ┆ --- │ │ i64 ┆ list[i64] │ ╞═════╪════════════╡ │ 0 ┆ [0] │ │ 4 ┆ [4] │ │ 5 ┆ [4, 5] │ │ 6 ┆ [4, 5, 6] │ │ 8 ┆ [6, 8] │ └─────┴────────────┘
如果你希望索引计数基于行号,那么你可能想要将
rolling与with_row_index()结合使用。
- row( ) tuple[Any, ...] | dict[str, Any][source]
通过索引或谓词获取单行的值。
- Parameters:
- index
行索引。
- by_predicate
根据给定的表达式/谓词选择行。
- named
返回一个字典而不是元组。字典是列名到行值的映射。这比返回常规元组更昂贵,但允许通过列名访问值。
- Returns:
- tuple (default) or dictionary of row values
警告
你绝对不应该使用这种方法来遍历DataFrame;如果你需要行迭代,你应该强烈推荐使用
iter_rows()来代替。注释
index和by_predicate参数是互斥的。此外,为了确保清晰性,by_predicate参数必须通过关键字提供。当使用
by_predicate时,如果返回的不是一行,则会出现错误;返回多行会引发TooManyRowsReturnedError,而返回零行则会引发NoRowsReturnedError(两者都继承自RowsError)。示例
指定一个索引以返回给定索引处的行作为元组。
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.row(2) (3, 8, 'c')
指定
named=True以获取一个字典,其中包含列名到行值的映射。>>> df.row(2, named=True) {'foo': 3, 'bar': 8, 'ham': 'c'}
使用
by_predicate返回与给定谓词匹配的行。>>> df.row(by_predicate=(pl.col("ham") == "b")) (2, 7, 'b')
- rows(
- *,
- named: bool = False,
返回DataFrame中的所有数据作为Python原生值的行列表。
默认情况下,每一行以与框架列相同的顺序返回为值的元组。设置
named=True将返回字典的行。- Parameters:
- named
返回字典而不是元组。字典是列名到行值的映射。这比返回常规元组更昂贵,但允许通过列名访问值。
- Returns:
- list of row value tuples (default), or list of dictionaries (if
named=True).
- list of row value tuples (default), or list of dictionaries (if
警告
行迭代不是最优的,因为底层数据是以列式存储的;在可能的情况下,优先使用专门的导出/输出方法之一进行导出。您还应考虑使用
iter_rows,以避免一次性物化所有数据;两者之间的性能差异不大,但如果分批处理行,峰值内存可以减少。另请参阅
iter_rows行迭代器遍历帧数据(不会具体化所有行)。
rows_by_key将帧数据具体化为一个键索引的字典。
注释
如果你有
ns精度的时间值,你应该知道Python原生只支持到μs精度;ns精度的值在转换为Python时将被截断为微秒。如果这对你的使用场景很重要,你应该导出为不同的格式(如Arrow或NumPy)。示例
>>> df = pl.DataFrame( ... { ... "x": ["a", "b", "b", "a"], ... "y": [1, 2, 3, 4], ... "z": [0, 3, 6, 9], ... } ... ) >>> df.rows() [('a', 1, 0), ('b', 2, 3), ('b', 3, 6), ('a', 4, 9)] >>> df.rows(named=True) [{'x': 'a', 'y': 1, 'z': 0}, {'x': 'b', 'y': 2, 'z': 3}, {'x': 'b', 'y': 3, 'z': 6}, {'x': 'a', 'y': 4, 'z': 9}]
- rows_by_key(
- key: ColumnNameOrSelector | Sequence[ColumnNameOrSelector],
- *,
- named: bool = False,
- include_key: bool = False,
- unique: bool = False,
返回所有数据作为以某列作为键的Python原生值的字典。
此方法类似于
rows,但不是以扁平列表的形式返回行,而是根据key列中的值对行进行分组,并以字典形式返回。请注意,由于将所有帧数据具体化为字典的高成本,不应使用此方法来替代本地操作;仅当您需要将值移出到无法直接与Polars/Arrow操作的Python数据结构或其他对象时,才应使用此方法。
- Parameters:
- key
用作返回字典的键的列。如果指定了多个列,则键将是这些值的元组,否则它将是一个字符串。
- named
返回字典行而不是元组,将列名映射到行值。
- include_key
将键值与关联数据内联(默认情况下,键值被省略作为内存/性能优化,因为它们可以从键中重新构建)。
- unique
表示键是唯一的;这将导致从键到单个关联行的1:1映射。请注意,如果键实际上不是唯一的,则将返回具有给定键的最后一行。
注释
如果你有
ns精度的时间值,你应该知道Python原生只支持到μs精度;ns精度的值在转换为Python时将被截断为微秒。如果这对你的使用场景很重要,你应该导出为不同的格式(如Arrow或NumPy)。示例
>>> df = pl.DataFrame( ... { ... "w": ["a", "b", "b", "a"], ... "x": ["q", "q", "q", "k"], ... "y": [1.0, 2.5, 3.0, 4.5], ... "z": [9, 8, 7, 6], ... } ... )
按给定的键列分组行:
>>> df.rows_by_key(key=["w"]) defaultdict(<class 'list'>, {'a': [('q', 1.0, 9), ('k', 4.5, 6)], 'b': [('q', 2.5, 8), ('q', 3.0, 7)]})
返回相同的行分组作为字典:
>>> df.rows_by_key(key=["w"], named=True) defaultdict(<class 'list'>, {'a': [{'x': 'q', 'y': 1.0, 'z': 9}, {'x': 'k', 'y': 4.5, 'z': 6}], 'b': [{'x': 'q', 'y': 2.5, 'z': 8}, {'x': 'q', 'y': 3.0, 'z': 7}]})
返回行分组,假设键是唯一的:
>>> df.rows_by_key(key=["z"], unique=True) {9: ('a', 'q', 1.0), 8: ('b', 'q', 2.5), 7: ('b', 'q', 3.0), 6: ('a', 'k', 4.5)}
返回行分组为字典,假设键是唯一的:
>>> df.rows_by_key(key=["z"], named=True, unique=True) {9: {'w': 'a', 'x': 'q', 'y': 1.0}, 8: {'w': 'b', 'x': 'q', 'y': 2.5}, 7: {'w': 'b', 'x': 'q', 'y': 3.0}, 6: {'w': 'a', 'x': 'k', 'y': 4.5}}
返回按复合键分组的字典行,包括键值:
>>> df.rows_by_key(key=["w", "x"], named=True, include_key=True) defaultdict(<class 'list'>, {('a', 'q'): [{'w': 'a', 'x': 'q', 'y': 1.0, 'z': 9}], ('b', 'q'): [{'w': 'b', 'x': 'q', 'y': 2.5, 'z': 8}, {'w': 'b', 'x': 'q', 'y': 3.0, 'z': 7}], ('a', 'k'): [{'w': 'a', 'x': 'k', 'y': 4.5, 'z': 6}]})
- sample(
- n: int | Series | None = None,
- *,
- fraction: float | Series | None = None,
- with_replacement: bool = False,
- shuffle: bool = False,
- seed: int | None = None,
从这个DataFrame中取样。
- Parameters:
- n
返回的项目数量。不能与
fraction一起使用。如果fraction为None,则默认为1。- fraction
返回项目的比例。不能与
n一起使用。- with_replacement
允许值被多次采样。
- shuffle
如果设置为True,采样行的顺序将被随机打乱。如果设置为False(默认值),返回行的顺序将既不稳定也不完全随机。
- seed
随机数生成器的种子。如果设置为None(默认值),则为每次采样操作生成一个随机种子。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.sample(n=2, seed=0) shape: (2, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 3 ┆ 8 ┆ c │ │ 2 ┆ 7 ┆ b │ └─────┴─────┴─────┘
- property schema: Schema[source]
获取列名到其数据类型的有序映射。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.schema Schema({'foo': Int64, 'bar': Float64, 'ham': String})
- select(
- *exprs: IntoExpr | Iterable[IntoExpr],
- **named_exprs: IntoExpr,
从这个DataFrame中选择列。
- Parameters:
- *exprs
要选择的列,指定为位置参数。 接受表达式输入。字符串被解析为列名, 其他非表达式输入被解析为字面量。
- **named_exprs
要选择的额外列,指定为关键字参数。 这些列将被重命名为所使用的关键字。
示例
传递列的名称以选择该列。
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.select("foo") shape: (3, 1) ┌─────┐ │ foo │ │ --- │ │ i64 │ ╞═════╡ │ 1 │ │ 2 │ │ 3 │ └─────┘
可以通过传递列名列表来选择多列。
>>> df.select(["foo", "bar"]) shape: (3, 2) ┌─────┬─────┐ │ foo ┆ bar │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 6 │ │ 2 ┆ 7 │ │ 3 ┆ 8 │ └─────┴─────┘
也可以使用位置参数而不是列表来选择多列。表达式也被接受。
>>> df.select(pl.col("foo"), pl.col("bar") + 1) shape: (3, 2) ┌─────┬─────┐ │ foo ┆ bar │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 7 │ │ 2 ┆ 8 │ │ 3 ┆ 9 │ └─────┴─────┘
使用关键字参数可以轻松命名您的表达式输入。
>>> df.select(threshold=pl.when(pl.col("foo") > 2).then(10).otherwise(0)) shape: (3, 1) ┌───────────┐ │ threshold │ │ --- │ │ i32 │ ╞═══════════╡ │ 0 │ │ 0 │ │ 10 │ └───────────┘
通过启用设置
Config.set_auto_structify(True),可以将具有多个输出的表达式自动实例化为结构体:>>> with pl.Config(auto_structify=True): ... df.select( ... is_odd=(pl.col(pl.Int64) % 2 == 1).name.suffix("_is_odd"), ... ) shape: (3, 1) ┌──────────────┐ │ is_odd │ │ --- │ │ struct[2] │ ╞══════════════╡ │ {true,false} │ │ {false,true} │ │ {true,false} │ └──────────────┘
- select_seq(
- *exprs: IntoExpr | Iterable[IntoExpr],
- **named_exprs: IntoExpr,
从这个DataFrame中选择列。
这将按顺序运行所有表达式,而不是并行运行。当每个表达式的工作量较小时使用此方法。
- Parameters:
- *exprs
要选择的列,指定为位置参数。 接受表达式输入。字符串被解析为列名, 其他非表达式输入被解析为字面量。
- **named_exprs
要选择的额外列,指定为关键字参数。 这些列将被重命名为所使用的关键字。
另请参阅
- serialize( ) bytes | str | None[source]
将此DataFrame序列化为JSON格式的文件或字符串。
- Parameters:
- file
文件路径或可写的类文件对象,结果将被写入其中。 如果设置为
None(默认值),则输出将作为字符串返回。- format
序列化的格式。选项:
"binary": 序列化为二进制格式(字节)。这是默认设置。"json": 序列化为JSON格式(字符串)。
注释
序列化在Polars版本之间不稳定:在一个Polars版本中序列化的LazyFrame可能无法在另一个Polars版本中反序列化。
示例
将DataFrame序列化为二进制表示。
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... } ... ) >>> bytes = df.serialize() >>> bytes b'x\x01bb@\x80\x15...'
字节可以稍后反序列化回DataFrame。
>>> import io >>> pl.DataFrame.deserialize(io.BytesIO(bytes)) shape: (3, 2) ┌─────┬─────┐ │ foo ┆ bar │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 6 │ │ 2 ┆ 7 │ │ 3 ┆ 8 │ └─────┴─────┘
- set_sorted( ) DataFrame[source]
指示一个或多个列已排序。
这可以加快未来的操作。
- Parameters:
- column
已排序的列
- descending
列是否按降序排序。
警告
如果数据未排序,这可能导致错误的结果!! 请谨慎使用!
- property shape: tuple[int, int][source]
获取DataFrame的形状。
示例
>>> df = pl.DataFrame({"foo": [1, 2, 3, 4, 5]}) >>> df.shape (5, 1)
- shift(n: int = 1, *, fill_value: IntoExpr | None = None) DataFrame[source]
将值按给定的索引数进行移动。
- Parameters:
- n
向前移动的索引数量。如果传递了负值,则值将向相反方向移动。
- fill_value
用此值填充结果中的空值。接受表达式输入。 非表达式输入将被解析为字面量。
注释
此方法类似于SQL中的
LAG操作,当n的值为正时。当n的值为负时,它类似于LEAD。示例
默认情况下,值会向前移动一个索引。
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 4], ... "b": [5, 6, 7, 8], ... } ... ) >>> df.shift() shape: (4, 2) ┌──────┬──────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞══════╪══════╡ │ null ┆ null │ │ 1 ┆ 5 │ │ 2 ┆ 6 │ │ 3 ┆ 7 │ └──────┴──────┘
传递一个负值以向相反方向移动。
>>> df.shift(-2) shape: (4, 2) ┌──────┬──────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞══════╪══════╡ │ 3 ┆ 7 │ │ 4 ┆ 8 │ │ null ┆ null │ │ null ┆ null │ └──────┴──────┘
指定
fill_value以填充结果中的空值。>>> df.shift(-2, fill_value=100) shape: (4, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 3 ┆ 7 │ │ 4 ┆ 8 │ │ 100 ┆ 100 │ │ 100 ┆ 100 │ └─────┴─────┘
- slice( ) DataFrame[source]
获取此DataFrame的一个切片。
- Parameters:
- offset
起始索引。支持负索引。
- length
切片的长度。如果设置为
None,将从偏移量开始选择所有行。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.slice(1, 2) shape: (2, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str │ ╞═════╪═════╪═════╡ │ 2 ┆ 7.0 ┆ b │ │ 3 ┆ 8.0 ┆ c │ └─────┴─────┴─────┘
- sort(
- by: IntoExpr | Iterable[IntoExpr],
- *more_by: IntoExpr,
- descending: bool | Sequence[bool] = False,
- nulls_last: bool | Sequence[bool] = False,
- multithreaded: bool = True,
- maintain_order: bool = False,
按给定的列对数据框进行排序。
- Parameters:
- by
要排序的列。接受表达式输入,包括选择器。字符串被解析为列名。
- *more_by
要排序的附加列,指定为位置参数。
- descending
按降序排序。当按多列排序时,可以通过传递布尔值序列来为每列指定。
- nulls_last
将空值放在最后;可以指定一个适用于所有列的布尔值,或者为每列控制指定一个布尔值序列。
- multithreaded
使用多线程进行排序。
- maintain_order
如果元素相等,是否应保持顺序。
示例
传递单个列名以按该列排序。
>>> df = pl.DataFrame( ... { ... "a": [1, 2, None], ... "b": [6.0, 5.0, 4.0], ... "c": ["a", "c", "b"], ... } ... ) >>> df.sort("a") shape: (3, 3) ┌──────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str │ ╞══════╪═════╪═════╡ │ null ┆ 4.0 ┆ b │ │ 1 ┆ 6.0 ┆ a │ │ 2 ┆ 5.0 ┆ c │ └──────┴─────┴─────┘
支持通过表达式进行排序。
>>> df.sort(pl.col("a") + pl.col("b") * 2, nulls_last=True) shape: (3, 3) ┌──────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str │ ╞══════╪═════╪═════╡ │ 2 ┆ 5.0 ┆ c │ │ 1 ┆ 6.0 ┆ a │ │ null ┆ 4.0 ┆ b │ └──────┴─────┴─────┘
通过传递列列表按多列排序。
>>> df.sort(["c", "a"], descending=True) shape: (3, 3) ┌──────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str │ ╞══════╪═════╪═════╡ │ 2 ┆ 5.0 ┆ c │ │ null ┆ 4.0 ┆ b │ │ 1 ┆ 6.0 ┆ a │ └──────┴─────┴─────┘
或者使用位置参数以相同的方式按多列排序。
>>> df.sort("c", "a", descending=[False, True]) shape: (3, 3) ┌──────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ str │ ╞══════╪═════╪═════╡ │ 1 ┆ 6.0 ┆ a │ │ null ┆ 4.0 ┆ b │ │ 2 ┆ 5.0 ┆ c │ └──────┴─────┴─────┘
- sql( ) DataFrame[source]
对DataFrame执行SQL查询。
在版本0.20.24中添加。
警告
此功能被认为是不稳定的,尽管它接近被认为是稳定的。它可能会在任何时候更改,而不被视为破坏性更改。
- Parameters:
- query
要执行的SQL查询。
- table_name
可选地提供一个明确的名称来表示调用帧的表(默认为“self”)。
另请参阅
注释
调用框架会自动在SQL上下文中注册为一个名为“self”的表。如果你想访问当前全局变量中的DataFrames和LazyFrames,请使用顶层的
pl.sql。通过使用
SQLContext对象,可以更好地控制注册和执行行为。SQL查询在收集并返回为DataFrame之前以惰性模式执行。
示例
>>> from datetime import date >>> df1 = pl.DataFrame( ... { ... "a": [1, 2, 3], ... "b": ["zz", "yy", "xx"], ... "c": [date(1999, 12, 31), date(2010, 10, 10), date(2077, 8, 8)], ... } ... )
使用SQL查询DataFrame:
>>> df1.sql("SELECT c, b FROM self WHERE a > 1") shape: (2, 2) ┌────────────┬─────┐ │ c ┆ b │ │ --- ┆ --- │ │ date ┆ str │ ╞════════════╪═════╡ │ 2010-10-10 ┆ yy │ │ 2077-08-08 ┆ xx │ └────────────┴─────┘
使用SQL对DataFrame应用转换,将“self”别名为“frame”。
>>> df1.sql( ... query=''' ... SELECT ... a, ... (a % 2 == 0) AS a_is_even, ... CONCAT_WS(':', b, b) AS b_b, ... EXTRACT(year FROM c) AS year, ... 0::float4 AS "zero", ... FROM frame ... ''', ... table_name="frame", ... ) shape: (3, 5) ┌─────┬───────────┬───────┬──────┬──────┐ │ a ┆ a_is_even ┆ b_b ┆ year ┆ zero │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ bool ┆ str ┆ i32 ┆ f32 │ ╞═════╪═══════════╪═══════╪══════╪══════╡ │ 1 ┆ false ┆ zz:zz ┆ 1999 ┆ 0.0 │ │ 2 ┆ true ┆ yy:yy ┆ 2010 ┆ 0.0 │ │ 3 ┆ false ┆ xx:xx ┆ 2077 ┆ 0.0 │ └─────┴───────────┴───────┴──────┴──────┘
- std(ddof: int = 1) DataFrame[source]
将此DataFrame的列聚合为其标准差值。
- Parameters:
- ddof
“自由度差值”:计算中使用的除数是 N - ddof, 其中 N 表示元素的数量。 默认情况下,ddof 为 1。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.std() shape: (1, 3) ┌─────┬─────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str │ ╞═════╪═════╪══════╡ │ 1.0 ┆ 1.0 ┆ null │ └─────┴─────┴──────┘ >>> df.std(ddof=0) shape: (1, 3) ┌──────────┬──────────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str │ ╞══════════╪══════════╪══════╡ │ 0.816497 ┆ 0.816497 ┆ null │ └──────────┴──────────┴──────┘
- property style: GT[source]
创建一个用于样式设计的优秀表格。
警告
此功能目前被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
Polars 本身不实现样式逻辑,而是依赖于 Great Tables 包。请参阅 Great Tables 参考 以获取更多信息和文档。
示例
导入一些样式助手,并创建示例数据:
>>> import polars.selectors as cs >>> from great_tables import loc, style >>> df = pl.DataFrame( ... { ... "site_id": [0, 1, 2], ... "measure_a": [5, 4, 6], ... "measure_b": [7, 3, 3], ... } ... )
强调将 site_id 作为行名:
>>> df.style.tab_stub(rowname_col="site_id")
为最高measure_a值的行填充背景:
>>> df.style.tab_style( ... style.fill("yellow"), ... loc.body(rows=pl.col("measure_a") == pl.col("measure_a").max()), ... )
在度量列上放置一个扳手(高级标签):
>>> df.style.tab_spanner( ... "Measures", cs.starts_with("measure") ... )
将measure_b值格式化为两位小数:
>>> df.style.fmt_number("measure_b", decimals=2)
- sum() DataFrame[source]
将此DataFrame的列聚合为其总和值。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.sum() shape: (1, 3) ┌─────┬─────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪══════╡ │ 6 ┆ 21 ┆ null │ └─────┴─────┴──────┘
- sum_horizontal(*, ignore_nulls: bool = True) Series[source]
水平跨列求和所有值。
- Parameters:
- ignore_nulls
忽略空值(默认)。 如果设置为
False,输入中的任何空值将导致输出为空。
- Returns:
- Series
一个名为
"sum"的 Series。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [4.0, 5.0, 6.0], ... } ... ) >>> df.sum_horizontal() shape: (3,) Series: 'sum' [f64] [ 5.0 7.0 9.0 ]
- tail(n: int = 5) DataFrame[source]
获取最后
n行。- Parameters:
- n
返回的行数。如果传递了负值,则返回除前
abs(n)行之外的所有行。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> df.tail(3) shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 3 ┆ 8 ┆ c │ │ 4 ┆ 9 ┆ d │ │ 5 ┆ 10 ┆ e │ └─────┴─────┴─────┘
传递一个负值以获取除前
abs(n)行之外的所有行。>>> df.tail(-3) shape: (2, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 4 ┆ 9 ┆ d │ │ 5 ┆ 10 ┆ e │ └─────┴─────┴─────┘
- to_arrow(
- *,
- compat_level: CompatLevel | None = None,
收集Arrow表中的底层箭头数组。
此操作大多是零拷贝。
- Data types that do copy:
分类类型
- Parameters:
- compat_level
在导出Polars的内部数据结构时使用特定的兼容性级别。
示例
>>> df = pl.DataFrame( ... {"foo": [1, 2, 3, 4, 5, 6], "bar": ["a", "b", "c", "d", "e", "f"]} ... ) >>> df.to_arrow() pyarrow.Table foo: int64 bar: large_string ---- foo: [[1,2,3,4,5,6]] bar: [["a","b","c","d","e","f"]]
- to_dict(*, as_series: bool = True) dict[str, Series] | dict[str, list[Any]][source]
将DataFrame转换为列名到值的字典映射。
- Parameters:
- as_series
True -> 值为Series False -> 值为List[Any]
另请参阅
示例
>>> df = pl.DataFrame( ... { ... "A": [1, 2, 3, 4, 5], ... "fruits": ["banana", "banana", "apple", "apple", "banana"], ... "B": [5, 4, 3, 2, 1], ... "cars": ["beetle", "audi", "beetle", "beetle", "beetle"], ... "optional": [28, 300, None, 2, -30], ... } ... ) >>> df shape: (5, 5) ┌─────┬────────┬─────┬────────┬──────────┐ │ A ┆ fruits ┆ B ┆ cars ┆ optional │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ str ┆ i64 ┆ str ┆ i64 │ ╞═════╪════════╪═════╪════════╪══════════╡ │ 1 ┆ banana ┆ 5 ┆ beetle ┆ 28 │ │ 2 ┆ banana ┆ 4 ┆ audi ┆ 300 │ │ 3 ┆ apple ┆ 3 ┆ beetle ┆ null │ │ 4 ┆ apple ┆ 2 ┆ beetle ┆ 2 │ │ 5 ┆ banana ┆ 1 ┆ beetle ┆ -30 │ └─────┴────────┴─────┴────────┴──────────┘ >>> df.to_dict(as_series=False) {'A': [1, 2, 3, 4, 5], 'fruits': ['banana', 'banana', 'apple', 'apple', 'banana'], 'B': [5, 4, 3, 2, 1], 'cars': ['beetle', 'audi', 'beetle', 'beetle', 'beetle'], 'optional': [28, 300, None, 2, -30]} >>> df.to_dict(as_series=True) {'A': shape: (5,) Series: 'A' [i64] [ 1 2 3 4 5 ], 'fruits': shape: (5,) Series: 'fruits' [str] [ "banana" "banana" "apple" "apple" "banana" ], 'B': shape: (5,) Series: 'B' [i64] [ 5 4 3 2 1 ], 'cars': shape: (5,) Series: 'cars' [str] [ "beetle" "audi" "beetle" "beetle" "beetle" ], 'optional': shape: (5,) Series: 'optional' [i64] [ 28 300 null 2 -30 ]}
- to_dicts() list[dict[str, Any]][source]
将每一行转换为Python原生值的字典。
注释
如果你有
ns精度的时间值,你应该知道Python原生只支持到μs精度;ns精度的值在转换为Python时将被截断为微秒。如果这对你的使用场景很重要,你应该导出为不同的格式(如Arrow或NumPy)。示例
>>> df = pl.DataFrame({"foo": [1, 2, 3], "bar": [4, 5, 6]}) >>> df.to_dicts() [{'foo': 1, 'bar': 4}, {'foo': 2, 'bar': 5}, {'foo': 3, 'bar': 6}]
- to_dummies(
- columns: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None,
- *,
- separator: str = '_',
- drop_first: bool = False,
将分类变量转换为虚拟/指示变量。
- Parameters:
- columns
应转换为虚拟变量的列名或选择器。如果设置为
None(默认值),则转换所有列。- separator
生成列名时使用的分隔符/定界符。
- drop_first
从正在编码的变量中移除第一个类别。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2], ... "bar": [3, 4], ... "ham": ["a", "b"], ... } ... ) >>> df.to_dummies() shape: (2, 6) ┌───────┬───────┬───────┬───────┬───────┬───────┐ │ foo_1 ┆ foo_2 ┆ bar_3 ┆ bar_4 ┆ ham_a ┆ ham_b │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ u8 ┆ u8 ┆ u8 ┆ u8 ┆ u8 ┆ u8 │ ╞═══════╪═══════╪═══════╪═══════╪═══════╪═══════╡ │ 1 ┆ 0 ┆ 1 ┆ 0 ┆ 1 ┆ 0 │ │ 0 ┆ 1 ┆ 0 ┆ 1 ┆ 0 ┆ 1 │ └───────┴───────┴───────┴───────┴───────┴───────┘
>>> df.to_dummies(drop_first=True) shape: (2, 3) ┌───────┬───────┬───────┐ │ foo_2 ┆ bar_4 ┆ ham_b │ │ --- ┆ --- ┆ --- │ │ u8 ┆ u8 ┆ u8 │ ╞═══════╪═══════╪═══════╡ │ 0 ┆ 0 ┆ 0 │ │ 1 ┆ 1 ┆ 1 │ └───────┴───────┴───────┘
>>> import polars.selectors as cs >>> df.to_dummies(cs.integer(), separator=":") shape: (2, 5) ┌───────┬───────┬───────┬───────┬─────┐ │ foo:1 ┆ foo:2 ┆ bar:3 ┆ bar:4 ┆ ham │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ u8 ┆ u8 ┆ u8 ┆ u8 ┆ str │ ╞═══════╪═══════╪═══════╪═══════╪═════╡ │ 1 ┆ 0 ┆ 1 ┆ 0 ┆ a │ │ 0 ┆ 1 ┆ 0 ┆ 1 ┆ b │ └───────┴───────┴───────┴───────┴─────┘
>>> df.to_dummies(cs.integer(), drop_first=True, separator=":") shape: (2, 3) ┌───────┬───────┬─────┐ │ foo:2 ┆ bar:4 ┆ ham │ │ --- ┆ --- ┆ --- │ │ u8 ┆ u8 ┆ str │ ╞═══════╪═══════╪═════╡ │ 0 ┆ 0 ┆ a │ │ 1 ┆ 1 ┆ b │ └───────┴───────┴─────┘
- to_init_repr(n: int = 1000) str[source]
将DataFrame转换为可实例化的字符串表示。
- Parameters:
- n
仅使用前n行。
示例
>>> df = pl.DataFrame( ... [ ... pl.Series("foo", [1, 2, 3], dtype=pl.UInt8), ... pl.Series("bar", [6.0, 7.0, 8.0], dtype=pl.Float32), ... pl.Series("ham", ["a", "b", "c"], dtype=pl.String), ... ] ... ) >>> print(df.to_init_repr()) pl.DataFrame( [ pl.Series('foo', [1, 2, 3], dtype=pl.UInt8), pl.Series('bar', [6.0, 7.0, 8.0], dtype=pl.Float32), pl.Series('ham', ['a', 'b', 'c'], dtype=pl.String), ] )
>>> df_from_str_repr = eval(df.to_init_repr()) >>> df_from_str_repr shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ u8 ┆ f32 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6.0 ┆ a │ │ 2 ┆ 7.0 ┆ b │ │ 3 ┆ 8.0 ┆ c │ └─────┴─────┴─────┘
- to_jax(
- return_type: JaxExportType = 'array',
- *,
- device: jax.Device | str | None = None,
- label: str | Expr | Sequence[str | Expr] | None = None,
- features: str | Expr | Sequence[str | Expr] | None = None,
- dtype: PolarsDataType | None = None,
- order: IndexOrder = 'fortran',
将DataFrame转换为Jax数组,或Jax数组的字典。
在版本0.20.27中添加。
警告
此功能目前被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
- Parameters:
- return_type{“array”, “dict”}
设置返回类型;一个Jax数组,或Jax数组的字典。
- device
指定将在其上创建数组的jax
Device;可以提供字符串(如“cpu”、“gpu”或“tpu”),在这种情况下,设备将作为jax.devices(string)[0]检索。为了更具体的控制,您可以直接提供实例化的Device。如果为None,则数组将在默认设备上创建。- label
一个或多个列名、表达式或选择器,用于标记特征数据;当
return_type为“dict”时,返回一个{"label": ..., "features": ...}字典,而不是{"col": array, }字典。- features
一个或多个包含特征数据的列名、表达式或选择器;如果省略,则使用所有未被指定为标签部分的列。仅当
return_type为“dict”时适用。- dtype
统一所有返回数组的dtype;在转换为数组之前,将任何尚未达到所需dtype的列进行类型转换。请注意,除非Jax配置/环境另有指示(例如:在启动时配置对象中设置了“jax_enable_x64”为True,或在环境中设置了“JAX_ENABLE_X64”为“1”),否则导出将是单精度(32位)。
- order{“c”, “fortran”}
返回的Jax数组的索引顺序,可以是C风格(行优先)或Fortran风格(列优先)。
另请参阅
示例
>>> df = pl.DataFrame( ... { ... "lbl": [0, 1, 2, 3], ... "feat1": [1, 0, 0, 1], ... "feat2": [1.5, -0.5, 0.0, -2.25], ... } ... )
标准返回类型(2D 数组),在标准设备上:
>>> df.to_jax() Array([[ 0. , 1. , 1.5 ], [ 1. , 0. , -0.5 ], [ 2. , 0. , 0. ], [ 3. , 1. , -2.25]], dtype=float32)
在默认的GPU设备上创建数组:
>>> a = df.to_jax(device="gpu") >>> a.device() GpuDevice(id=0, process_index=0)
在特定的GPU设备上创建数组:
>>> gpu_device = jax.devices("gpu")[1] >>> a = df.to_jax(device=gpu_device) >>> a.device() GpuDevice(id=1, process_index=0)
作为单个数组的字典:
>>> df.to_jax("dict") {'lbl': Array([0, 1, 2, 3], dtype=int32), 'feat1': Array([1, 0, 0, 1], dtype=int32), 'feat2': Array([ 1.5 , -0.5 , 0. , -2.25], dtype=float32)}
作为一个“标签”和“特征”字典;注意,由于“特征”未被声明,它默认为所有不在“标签”中的列:
>>> df.to_jax("dict", label="lbl") {'label': Array([[0], [1], [2], [3]], dtype=int32), 'features': Array([[ 1. , 1.5 ], [ 0. , -0.5 ], [ 0. , 0. ], [ 1. , -2.25]], dtype=float32)}
作为一个“标签”和“特征”字典,其中每个都使用列或选择器表达式指定(如果标签和特征用不同的数据类型表示更好,也可以用于转换数据):
>>> import polars.selectors as cs >>> df.to_jax( ... return_type="dict", ... features=cs.float(), ... label=pl.col("lbl").cast(pl.UInt8), ... ) {'label': Array([[0], [1], [2], [3]], dtype=uint8), 'features': Array([[ 1.5 ], [-0.5 ], [ 0. ], [-2.25]], dtype=float32)}
- to_numpy(
- *,
- order: IndexOrder = 'fortran',
- writable: bool = False,
- allow_copy: bool = True,
- structured: bool = False,
- use_pyarrow: bool | None = None,
将此DataFrame转换为NumPy ndarray。
此操作仅在必要时复制数据。当满足以下所有条件时,转换是零拷贝:
DataFrame 在内存中是完全连续的,所有 Series 都是背靠背的,并且所有 Series 都由一个单独的块组成。
数据类型是整数或浮点数。
DataFrame 不包含空值。
order参数设置为fortran(默认)。writable参数设置为False(默认值)。
- Parameters:
- order
返回的NumPy数组的索引顺序,可以是C风格或Fortran风格。通常,使用Fortran风格的索引顺序更快。然而,对于下游应用程序,使用C风格的顺序可能更合适,以防止数据克隆,例如在重塑为一维数组时。
- writable
确保生成的数组是可写的。如果数组是在没有复制的情况下创建的,这将强制复制数据,因为底层的Arrow数据是不可变的。
- allow_copy
允许复制内存以执行转换。如果设置为
False,会导致非零拷贝的转换失败。- structured
返回一个结构化数组,其数据类型对应于DataFrame的模式。如果设置为
False(默认值),则返回一个2D ndarray。- use_pyarrow
-
必要时转换为NumPy的函数。
自版本0.20.28起已弃用:Polars现在默认使用其本地引擎进行转换为NumPy。
示例
在某些情况下,没有空值的数值数据可以在不复制数据的情况下进行转换。 生成的数组将不可写。
>>> df = pl.DataFrame({"a": [1, 2, 3]}) >>> arr = df.to_numpy() >>> arr array([[1], [2], [3]]) >>> arr.flags.writeable False
设置
writable=True以强制复制数据使数组可写。>>> df.to_numpy(writable=True).flags.writeable True
如果DataFrame包含不同的数值数据类型,结果的数据类型将是超类型。这需要复制数据。带有空值的整数类型将被转换为浮点类型,其中
nan表示空值。>>> df = pl.DataFrame({"a": [1, 2, None], "b": [4.0, 5.0, 6.0]}) >>> df.to_numpy() array([[ 1., 4.], [ 2., 5.], [nan, 6.]])
设置
allow_copy=False以在数据将被复制时引发错误。>>> s.to_numpy(allow_copy=False) Traceback (most recent call last): ... RuntimeError: copy not allowed: cannot convert to a NumPy array without copying data
Polars 默认使用 F 连续顺序。使用
order="c"强制生成的数组为 C 连续顺序。>>> df.to_numpy(order="c").flags.c_contiguous True
具有混合类型的DataFrames将生成一个具有对象dtype的数组。
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.5, 7.0, 8.5], ... "ham": ["a", "b", "c"], ... }, ... schema_overrides={"foo": pl.UInt8, "bar": pl.Float32}, ... ) >>> df.to_numpy() array([[1, 6.5, 'a'], [2, 7.0, 'b'], [3, 8.5, 'c']], dtype=object)
设置
structured=True以转换为结构化数组,这样可以更好地保留各个列的数据,如名称和数据类型。>>> df.to_numpy(structured=True) array([(1, 6.5, 'a'), (2, 7. , 'b'), (3, 8.5, 'c')], dtype=[('foo', 'u1'), ('bar', '<f4'), ('ham', '<U1')])
- to_pandas( ) DataFrame[source]
将此DataFrame转换为pandas DataFrame。
如果未启用
use_pyarrow_extension_array,此操作将复制数据。- Parameters:
- use_pyarrow_extension_array
使用PyArrow支持的扩展数组代替NumPy数组作为pandas DataFrame的列。这允许零拷贝操作并保留空值。如果PyArrow计算函数不支持这些操作,则对生成的pandas DataFrame的后续操作可能会触发转换为NumPy。
- **kwargs
额外的关键字参数将传递给
pyarrow.Table.to_pandas().
- Returns:
注释
此操作要求同时安装
pandas和pyarrow。示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6.0, 7.0, 8.0], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.to_pandas() foo bar ham 0 1 6.0 a 1 2 7.0 b 2 3 8.0 c
数值列中的空值被转换为
NaN。>>> df = pl.DataFrame( ... { ... "foo": [1, 2, None], ... "bar": [6.0, None, 8.0], ... "ham": [None, "b", "c"], ... } ... ) >>> df.to_pandas() foo bar ham 0 1.0 6.0 None 1 2.0 NaN b 2 NaN 8.0 c
传递
use_pyarrow_extension_array=True以获取一个由 PyArrow 扩展数组支持的 pandas DataFrame。这将保留空值。>>> df.to_pandas(use_pyarrow_extension_array=True) foo bar ham 0 1 6.0 <NA> 1 2 <NA> b 2 <NA> 8.0 c >>> _.dtypes foo int64[pyarrow] bar double[pyarrow] ham large_string[pyarrow] dtype: object
- to_series(index: int = 0) Series[source]
在索引位置选择列作为Series。
- Parameters:
- index
选择的位置。
另请参阅
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.to_series(1) shape: (3,) Series: 'bar' [i64] [ 6 7 8 ]
- to_struct(name: str = '') Series[source]
将
DataFrame转换为类型为Struct的Series。- Parameters:
- name
结构体Series的名称
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 4, 5], ... "b": ["one", "two", "three", "four", "five"], ... } ... ) >>> df.to_struct("nums") shape: (5,) Series: 'nums' [struct[2]] [ {1,"one"} {2,"two"} {3,"three"} {4,"four"} {5,"five"} ]
- to_torch(
- return_type: TorchExportType = 'tensor',
- *,
- label: str | Expr | Sequence[str | Expr] | None = None,
- features: str | Expr | Sequence[str | Expr] | None = None,
- dtype: PolarsDataType | None = None,
将DataFrame转换为PyTorch张量、数据集或张量字典。
在版本0.20.23中添加。
警告
此功能目前被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
- Parameters:
- return_type{“tensor”, “dataset”, “dict”}
设置返回类型;可以是PyTorch Tensor、PolarsDataset(一种专门用于帧的TensorDataset)或Tensors的字典。
- label
一个或多个列名、表达式或选择器,用于标记特征数据;当
return_type为“dataset”时,PolarsDataset将为每一行返回(features, label)张量元组。否则,它将返回(features,)张量元组,其中特征包含所有行数据。- features
一个或多个包含特征数据的列名、表达式或选择器;如果省略,则使用所有未被指定为标签部分的列。
- dtype
统一所有返回张量的数据类型;在转换为张量之前,将任何不符合要求数据类型的列进行转换。这包括标签列除非标签是一个表达式(例如
pl.col("label_column").cast(pl.Int16))。
另请参阅
示例
>>> df = pl.DataFrame( ... { ... "lbl": [0, 1, 2, 3], ... "feat1": [1, 0, 0, 1], ... "feat2": [1.5, -0.5, 0.0, -2.25], ... } ... )
标准返回类型(Tensor),具有f32超类型:
>>> df.to_torch(dtype=pl.Float32) tensor([[ 0.0000, 1.0000, 1.5000], [ 1.0000, 0.0000, -0.5000], [ 2.0000, 0.0000, 0.0000], [ 3.0000, 1.0000, -2.2500]])
作为单个张量的字典:
>>> df.to_torch("dict") {'lbl': tensor([0, 1, 2, 3]), 'feat1': tensor([1, 0, 0, 1]), 'feat2': tensor([ 1.5000, -0.5000, 0.0000, -2.2500], dtype=torch.float64)}
作为一个“标签”和“特征”字典;注意,由于“特征”未被声明,它默认为所有不在“标签”中的列:
>>> df.to_torch("dict", label="lbl", dtype=pl.Float32) {'label': tensor([[0.], [1.], [2.], [3.]]), 'features': tensor([[ 1.0000, 1.5000], [ 0.0000, -0.5000], [ 0.0000, 0.0000], [ 1.0000, -2.2500]])}
作为一个 PolarsDataset,具有 f64 超类型:
>>> ds = df.to_torch("dataset", dtype=pl.Float64) >>> ds[3] (tensor([ 3.0000, 1.0000, -2.2500], dtype=torch.float64),) >>> ds[:2] (tensor([[ 0.0000, 1.0000, 1.5000], [ 1.0000, 0.0000, -0.5000]], dtype=torch.float64),) >>> ds[[0, 3]] (tensor([[ 0.0000, 1.0000, 1.5000], [ 3.0000, 1.0000, -2.2500]], dtype=torch.float64),)
为了方便,PolarsDataset可以选择使用半精度数据进行实验(通常这会在模型/管道上设置):
>>> list(ds.half()) [(tensor([0.0000, 1.0000, 1.5000], dtype=torch.float16),), (tensor([ 1.0000, 0.0000, -0.5000], dtype=torch.float16),), (tensor([2., 0., 0.], dtype=torch.float16),), (tensor([ 3.0000, 1.0000, -2.2500], dtype=torch.float16),)]
将PolarsDataset传递给DataLoader,指定标签:
>>> from torch.utils.data import DataLoader >>> ds = df.to_torch("dataset", label="lbl") >>> dl = DataLoader(ds, batch_size=2) >>> batches = list(dl) >>> batches[0] [tensor([[ 1.0000, 1.5000], [ 0.0000, -0.5000]], dtype=torch.float64), tensor([0, 1])]
请注意,标签可以作为表达式给出,允许它们具有与特征列无关的dtype(支持多列标签)。
>>> ds = df.to_torch( ... return_type="dataset", ... dtype=pl.Float32, ... label=pl.col("lbl").cast(pl.Int16), ... ) >>> ds[:2] (tensor([[ 1.0000, 1.5000], [ 0.0000, -0.5000]]), tensor([0, 1], dtype=torch.int16))
轻松集成(例如)scikit-learn 和其他数据集:
>>> from sklearn.datasets import fetch_california_housing >>> housing = fetch_california_housing() >>> df = pl.DataFrame( ... data=housing.data, ... schema=housing.feature_names, ... ).with_columns( ... Target=housing.target, ... ) >>> train = df.to_torch("dataset", label="Target") >>> loader = DataLoader( ... train, ... shuffle=True, ... batch_size=64, ... )
- top_k( ) DataFrame[source]
返回
k个最大的行。非空元素总是优先于空元素,无论
reverse的值如何。输出不保证按任何特定顺序排列,如果您希望输出排序,请在此函数之后调用sort()。- Parameters:
- k
返回的行数。
- by
用于确定顶部行的列。 接受表达式输入。字符串被解析为列名。
- reverse
考虑
by列中的k个最小元素(而不是k个最大元素)。可以通过传递一个布尔值序列来为每列指定这一点。
另请参阅
示例
>>> df = pl.DataFrame( ... { ... "a": ["a", "b", "a", "b", "b", "c"], ... "b": [2, 1, 1, 3, 2, 1], ... } ... )
获取包含列 b 中 4 个最大值的行。
>>> df.top_k(4, by="b") shape: (4, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ str ┆ i64 │ ╞═════╪═════╡ │ b ┆ 3 │ │ a ┆ 2 │ │ b ┆ 2 │ │ b ┆ 1 │ └─────┴─────┘
获取在列b和a上排序时包含4个最大值的行。
>>> df.top_k(4, by=["b", "a"]) shape: (4, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ │ str ┆ i64 │ ╞═════╪═════╡ │ b ┆ 3 │ │ b ┆ 2 │ │ a ┆ 2 │ │ c ┆ 1 │ └─────┴─────┘
- transpose(
- *,
- include_header: bool = False,
- header_name: str = 'column',
- column_names: str | Iterable[str] | None = None,
将DataFrame沿对角线进行转置。
- Parameters:
- include_header
如果设置,列名将作为第一列添加。
- header_name
如果设置了
include_header,这将决定将要插入的列的名称。- column_names
可选的迭代器生成字符串或命名现有列的字符串。 这些将命名转置数据中的值(非标题)列。
- Returns:
- DataFrame
注释
这是一个非常昂贵的操作。也许你可以用不同的方式来做。
示例
>>> df = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}) >>> df.transpose(include_header=True) shape: (2, 4) ┌────────┬──────────┬──────────┬──────────┐ │ column ┆ column_0 ┆ column_1 ┆ column_2 │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 ┆ i64 │ ╞════════╪══════════╪══════════╪══════════╡ │ a ┆ 1 ┆ 2 ┆ 3 │ │ b ┆ 4 ┆ 5 ┆ 6 │ └────────┴──────────┴──────────┴──────────┘
用列表替换自动生成的列名
>>> df.transpose(include_header=False, column_names=["x", "y", "z"]) shape: (2, 3) ┌─────┬─────┬─────┐ │ x ┆ y ┆ z │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 1 ┆ 2 ┆ 3 │ │ 4 ┆ 5 ┆ 6 │ └─────┴─────┴─────┘
将标题作为单独的列包含
>>> df.transpose( ... include_header=True, header_name="foo", column_names=["x", "y", "z"] ... ) shape: (2, 4) ┌─────┬─────┬─────┬─────┐ │ foo ┆ x ┆ y ┆ z │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╪═════╡ │ a ┆ 1 ┆ 2 ┆ 3 │ │ b ┆ 4 ┆ 5 ┆ 6 │ └─────┴─────┴─────┴─────┘
用生成器函数中的列名替换自动生成的列
>>> def name_generator(): ... base_name = "my_column_" ... count = 0 ... while True: ... yield f"{base_name}{count}" ... count += 1 >>> df.transpose(include_header=False, column_names=name_generator()) shape: (2, 3) ┌─────────────┬─────────────┬─────────────┐ │ my_column_0 ┆ my_column_1 ┆ my_column_2 │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════════════╪═════════════╪═════════════╡ │ 1 ┆ 2 ┆ 3 │ │ 4 ┆ 5 ┆ 6 │ └─────────────┴─────────────┴─────────────┘
使用现有列作为新列名
>>> df = pl.DataFrame(dict(id=["i", "j", "k"], a=[1, 2, 3], b=[4, 5, 6])) >>> df.transpose(column_names="id") shape: (2, 3) ┌─────┬─────┬─────┐ │ i ┆ j ┆ k │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 1 ┆ 2 ┆ 3 │ │ 4 ┆ 5 ┆ 6 │ └─────┴─────┴─────┘ >>> df.transpose(include_header=True, header_name="new_id", column_names="id") shape: (2, 4) ┌────────┬─────┬─────┬─────┐ │ new_id ┆ i ┆ j ┆ k │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ i64 ┆ i64 │ ╞════════╪═════╪═════╪═════╡ │ a ┆ 1 ┆ 2 ┆ 3 │ │ b ┆ 4 ┆ 5 ┆ 6 │ └────────┴─────┴─────┴─────┘
- unique(
- subset: ColumnNameOrSelector | Collection[ColumnNameOrSelector] | None = None,
- *,
- keep: UniqueKeepStrategy = 'any',
- maintain_order: bool = False,
从这个数据框中删除重复的行。
- Parameters:
- subset
列名或选择器,用于在识别重复行时考虑。如果设置为
None(默认值),则使用所有列。- keep{‘first’, ‘last’, ‘any’, ‘none’}
保留哪些重复行。
- ‘any’: Does not give any guarantee of which row is kept.
这允许更多的优化。
‘none’: 不保留重复的行。
‘first’: 保留第一个唯一的行。
‘last’: 保留最后一行唯一行。
- maintain_order
保持与原始DataFrame相同的顺序。这需要更高的计算成本。 将此设置为
True会阻止在流引擎上运行的可能性。
- Returns:
- DataFrame
具有唯一行的DataFrame。
警告
如果DataFrame或子集中有类型为
List的列,则此方法将失败。注释
如果你来自pandas,这类似于
pandas.DataFrame.drop_duplicates。示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 1], ... "bar": ["a", "a", "a", "a"], ... "ham": ["b", "b", "b", "b"], ... } ... ) >>> df.unique(maintain_order=True) shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ str ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ a ┆ b │ │ 2 ┆ a ┆ b │ │ 3 ┆ a ┆ b │ └─────┴─────┴─────┘ >>> df.unique(subset=["bar", "ham"], maintain_order=True) shape: (1, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ str ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ a ┆ b │ └─────┴─────┴─────┘ >>> df.unique(keep="last", maintain_order=True) shape: (3, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ str ┆ str │ ╞═════╪═════╪═════╡ │ 2 ┆ a ┆ b │ │ 3 ┆ a ┆ b │ │ 1 ┆ a ┆ b │ └─────┴─────┴─────┘
- unnest(
- columns: ColumnNameOrSelector | Collection[ColumnNameOrSelector],
- *more_columns: ColumnNameOrSelector,
将结构体列分解为每个字段的单独列。
新列将被插入到数据框中结构列的位置。
- Parameters:
- columns
应该被解构的结构体列的名称。
- *more_columns
要解嵌套的额外列,指定为位置参数。
示例
>>> df = pl.DataFrame( ... { ... "before": ["foo", "bar"], ... "t_a": [1, 2], ... "t_b": ["a", "b"], ... "t_c": [True, None], ... "t_d": [[1, 2], [3]], ... "after": ["baz", "womp"], ... } ... ).select("before", pl.struct(pl.col("^t_.$")).alias("t_struct"), "after") >>> df shape: (2, 3) ┌────────┬─────────────────────┬───────┐ │ before ┆ t_struct ┆ after │ │ --- ┆ --- ┆ --- │ │ str ┆ struct[4] ┆ str │ ╞════════╪═════════════════════╪═══════╡ │ foo ┆ {1,"a",true,[1, 2]} ┆ baz │ │ bar ┆ {2,"b",null,[3]} ┆ womp │ └────────┴─────────────────────┴───────┘ >>> df.unnest("t_struct") shape: (2, 6) ┌────────┬─────┬─────┬──────┬───────────┬───────┐ │ before ┆ t_a ┆ t_b ┆ t_c ┆ t_d ┆ after │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ str ┆ bool ┆ list[i64] ┆ str │ ╞════════╪═════╪═════╪══════╪═══════════╪═══════╡ │ foo ┆ 1 ┆ a ┆ true ┆ [1, 2] ┆ baz │ │ bar ┆ 2 ┆ b ┆ null ┆ [3] ┆ womp │ └────────┴─────┴─────┴──────┴───────────┴───────┘
- unpivot(
- on: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None,
- *,
- index: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None,
- variable_name: str | None = None,
- value_name: str | None = None,
将DataFrame从宽格式转换为长格式。
可选地保留标识符设置。
此函数有助于将DataFrame整理成一种格式,其中一列或多列是标识符变量(索引),而所有其他列,被视为测量变量(on),被“逆透视”到行轴,只留下两个非标识符列,'variable'和'value'。
- Parameters:
- on
用作值变量的列或选择器;如果
on为空,则将使用不在index中的所有列。- index
用作标识符变量的列或选择器。
- variable_name
为
variable列指定的名称。默认为“variable”- value_name
为
value列指定的名称。默认为“value”
注释
如果你来自pandas,这类似于
pandas.DataFrame.melt, 但是用index替换id_vars,用on替换value_vars。 在其他框架中,你可能知道这个操作为pivot_longer。示例
>>> df = pl.DataFrame( ... { ... "a": ["x", "y", "z"], ... "b": [1, 3, 5], ... "c": [2, 4, 6], ... } ... ) >>> import polars.selectors as cs >>> df.unpivot(cs.numeric(), index="a") shape: (6, 3) ┌─────┬──────────┬───────┐ │ a ┆ variable ┆ value │ │ --- ┆ --- ┆ --- │ │ str ┆ str ┆ i64 │ ╞═════╪══════════╪═══════╡ │ x ┆ b ┆ 1 │ │ y ┆ b ┆ 3 │ │ z ┆ b ┆ 5 │ │ x ┆ c ┆ 2 │ │ y ┆ c ┆ 4 │ │ z ┆ c ┆ 6 │ └─────┴──────────┴───────┘
- unstack(
- step: int,
- how: UnstackDirection = 'vertical',
- columns: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None,
- fill_values: list[Any] | None = None,
将长表展开为宽表形式,而不进行聚合操作。
警告
此功能被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
这可能比透视表快得多,因为它可以跳过分组阶段。
- Parameters:
- step
未堆叠框架中的行数。
- how{ ‘vertical’, ‘horizontal’ }
解堆叠的方向。
- columns
要包含在操作中的列名或选择器。 如果设置为
None(默认值),则使用所有列。- fill_values
用此值填充不适合新大小的值。
示例
>>> from string import ascii_uppercase >>> df = pl.DataFrame( ... { ... "x": list(ascii_uppercase[0:8]), ... "y": pl.int_range(1, 9, eager=True), ... } ... ).with_columns( ... z=pl.int_ranges(pl.col("y"), pl.col("y") + 2, dtype=pl.UInt8), ... ) >>> df shape: (8, 3) ┌─────┬─────┬──────────┐ │ x ┆ y ┆ z │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ list[u8] │ ╞═════╪═════╪══════════╡ │ A ┆ 1 ┆ [1, 2] │ │ B ┆ 2 ┆ [2, 3] │ │ C ┆ 3 ┆ [3, 4] │ │ D ┆ 4 ┆ [4, 5] │ │ E ┆ 5 ┆ [5, 6] │ │ F ┆ 6 ┆ [6, 7] │ │ G ┆ 7 ┆ [7, 8] │ │ H ┆ 8 ┆ [8, 9] │ └─────┴─────┴──────────┘ >>> df.unstack(step=4, how="vertical") shape: (4, 6) ┌─────┬─────┬─────┬─────┬──────────┬──────────┐ │ x_0 ┆ x_1 ┆ y_0 ┆ y_1 ┆ z_0 ┆ z_1 │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ str ┆ i64 ┆ i64 ┆ list[u8] ┆ list[u8] │ ╞═════╪═════╪═════╪═════╪══════════╪══════════╡ │ A ┆ E ┆ 1 ┆ 5 ┆ [1, 2] ┆ [5, 6] │ │ B ┆ F ┆ 2 ┆ 6 ┆ [2, 3] ┆ [6, 7] │ │ C ┆ G ┆ 3 ┆ 7 ┆ [3, 4] ┆ [7, 8] │ │ D ┆ H ┆ 4 ┆ 8 ┆ [4, 5] ┆ [8, 9] │ └─────┴─────┴─────┴─────┴──────────┴──────────┘ >>> df.unstack(step=2, how="horizontal") shape: (4, 6) ┌─────┬─────┬─────┬─────┬──────────┬──────────┐ │ x_0 ┆ x_1 ┆ y_0 ┆ y_1 ┆ z_0 ┆ z_1 │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ str ┆ i64 ┆ i64 ┆ list[u8] ┆ list[u8] │ ╞═════╪═════╪═════╪═════╪══════════╪══════════╡ │ A ┆ B ┆ 1 ┆ 2 ┆ [1, 2] ┆ [2, 3] │ │ C ┆ D ┆ 3 ┆ 4 ┆ [3, 4] ┆ [4, 5] │ │ E ┆ F ┆ 5 ┆ 6 ┆ [5, 6] ┆ [6, 7] │ │ G ┆ H ┆ 7 ┆ 8 ┆ [7, 8] ┆ [8, 9] │ └─────┴─────┴─────┴─────┴──────────┴──────────┘ >>> import polars.selectors as cs >>> df.unstack(step=5, columns=cs.numeric(), fill_values=0) shape: (5, 2) ┌─────┬─────┐ │ y_0 ┆ y_1 │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 6 │ │ 2 ┆ 7 │ │ 3 ┆ 8 │ │ 4 ┆ 0 │ │ 5 ┆ 0 │ └─────┴─────┘
- update(
- other: DataFrame,
- on: str | Sequence[str] | None = None,
- how: Literal['left', 'inner', 'full'] = 'left',
- *,
- left_on: str | Sequence[str] | None = None,
- right_on: str | Sequence[str] | None = None,
- include_nulls: bool = False,
使用
other中的值更新此DataFrame中的值。警告
此功能被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
- Parameters:
- other
将用于更新值的DataFrame
- on
将用于连接的列名。如果设置为
None(默认值),则使用每个框架的隐式行索引作为连接键。- how{‘left’, ‘inner’, ‘full’}
'left' 将保留左表中的所有行;如果右表中的多行与左行的键匹配,则行可能会重复。
‘inner’ 只保留那些键在两个框架中都存在的行。
'full' 将更新键匹配的现有行,同时添加给定帧中包含的任何新行。
- left_on
连接左侧DataFrame的列。
- right_on
连接右侧DataFrame的列。
- include_nulls
用右侧框架中的空值覆盖左侧框架中的值。 如果设置为
False(默认值),则忽略右侧框架中的空值。
注释
这是左连接/内连接的语法糖,当
include_nulls = False时,可以选择使用coalesce示例
>>> df = pl.DataFrame( ... { ... "A": [1, 2, 3, 4], ... "B": [400, 500, 600, 700], ... } ... ) >>> df shape: (4, 2) ┌─────┬─────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ 400 │ │ 2 ┆ 500 │ │ 3 ┆ 600 │ │ 4 ┆ 700 │ └─────┴─────┘ >>> new_df = pl.DataFrame( ... { ... "B": [-66, None, -99], ... "C": [5, 3, 1], ... } ... )
使用
new_df中的非空值按行索引更新df的值:>>> df.update(new_df) shape: (4, 2) ┌─────┬─────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ -66 │ │ 2 ┆ 500 │ │ 3 ┆ -99 │ │ 4 ┆ 700 │ └─────┴─────┘
使用
new_df中的非空值按行索引更新df的值,但仅保留两个框架中共有的行:>>> df.update(new_df, how="inner") shape: (3, 2) ┌─────┬─────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ -66 │ │ 2 ┆ 500 │ │ 3 ┆ -99 │ └─────┴─────┘
使用
new_df中的非空值更新df值,采用全外连接策略,该策略在每个框架中定义了明确的连接列:>>> df.update(new_df, left_on=["A"], right_on=["C"], how="full") shape: (5, 2) ┌─────┬─────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪═════╡ │ 1 ┆ -99 │ │ 2 ┆ 500 │ │ 3 ┆ 600 │ │ 4 ┆ 700 │ │ 5 ┆ -66 │ └─────┴─────┘
更新
df值,包括new_df中的空值,使用全外连接策略,该策略在每个框架中定义了明确的连接列:>>> df.update(new_df, left_on="A", right_on="C", how="full", include_nulls=True) shape: (5, 2) ┌─────┬──────┐ │ A ┆ B │ │ --- ┆ --- │ │ i64 ┆ i64 │ ╞═════╪══════╡ │ 1 ┆ -99 │ │ 2 ┆ 500 │ │ 3 ┆ null │ │ 4 ┆ 700 │ │ 5 ┆ -66 │ └─────┴──────┘
- upsample(
- time_column: str,
- *,
- every: str | timedelta,
- group_by: str | Sequence[str] | None = None,
- maintain_order: bool = False,
以固定频率对DataFrame进行上采样。
every参数是用以下字符串语言创建的:1纳秒 (1 纳秒)
1微秒 (1 微秒)
1毫秒 (1 毫秒)
1秒 (1 秒)
1分钟 (1 minute)
1小时 (1小时)
1d (1个日历日)
1w (1个日历周)
1个月 (1个日历月)
1q (1个日历季度)
1年 (1个日历年)
1i (1 索引计数)
或者将它们组合起来:
“3d12h4m25s” # 3天,12小时,4分钟,25秒
“日历日”指的是第二天的相应时间(由于夏令时,可能不是24小时)。同样适用于“日历周”、“日历月”、“日历季度”和“日历年”。
- Parameters:
- time_column
时间列将用于确定日期范围。 请注意,为了使输出有意义,此列必须排序。
- every
间隔将开始‘每’持续时间。
- group_by
首先按这些列进行分组,然后对每个组进行上采样。
- maintain_order
保持顺序可预测。这会更慢。
- Returns:
- DataFrame
结果将按
time_column排序(但请注意,如果传递了group_by列,则仅在每个组内排序)。
示例
按一定间隔对DataFrame进行上采样。
>>> from datetime import datetime >>> df = pl.DataFrame( ... { ... "time": [ ... datetime(2021, 2, 1), ... datetime(2021, 4, 1), ... datetime(2021, 5, 1), ... datetime(2021, 6, 1), ... ], ... "groups": ["A", "B", "A", "B"], ... "values": [0, 1, 2, 3], ... } ... ).set_sorted("time") >>> df.upsample( ... time_column="time", every="1mo", group_by="groups", maintain_order=True ... ).select(pl.all().forward_fill()) shape: (7, 3) ┌─────────────────────┬────────┬────────┐ │ time ┆ groups ┆ values │ │ --- ┆ --- ┆ --- │ │ datetime[μs] ┆ str ┆ i64 │ ╞═════════════════════╪════════╪════════╡ │ 2021-02-01 00:00:00 ┆ A ┆ 0 │ │ 2021-03-01 00:00:00 ┆ A ┆ 0 │ │ 2021-04-01 00:00:00 ┆ A ┆ 0 │ │ 2021-05-01 00:00:00 ┆ A ┆ 2 │ │ 2021-04-01 00:00:00 ┆ B ┆ 1 │ │ 2021-05-01 00:00:00 ┆ B ┆ 1 │ │ 2021-06-01 00:00:00 ┆ B ┆ 3 │ └─────────────────────┴────────┴────────┘
- var(ddof: int = 1) DataFrame[source]
将此DataFrame的列聚合为其方差值。
- Parameters:
- ddof
“自由度差值”:计算中使用的除数是 N - ddof, 其中 N 表示元素的数量。 默认情况下,ddof 为 1。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... "ham": ["a", "b", "c"], ... } ... ) >>> df.var() shape: (1, 3) ┌─────┬─────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str │ ╞═════╪═════╪══════╡ │ 1.0 ┆ 1.0 ┆ null │ └─────┴─────┴──────┘ >>> df.var(ddof=0) shape: (1, 3) ┌──────────┬──────────┬──────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ str │ ╞══════════╪══════════╪══════╡ │ 0.666667 ┆ 0.666667 ┆ null │ └──────────┴──────────┴──────┘
- vstack(
- other: DataFrame,
- *,
- in_place: bool = False,
通过将一个DataFrame堆叠到它上面,垂直扩展这个DataFrame。
- Parameters:
- other
要堆叠的DataFrame。
- in_place
就地修改。
另请参阅
示例
>>> df1 = pl.DataFrame( ... { ... "foo": [1, 2], ... "bar": [6, 7], ... "ham": ["a", "b"], ... } ... ) >>> df2 = pl.DataFrame( ... { ... "foo": [3, 4], ... "bar": [8, 9], ... "ham": ["c", "d"], ... } ... ) >>> df1.vstack(df2) shape: (4, 3) ┌─────┬─────┬─────┐ │ foo ┆ bar ┆ ham │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ │ 1 ┆ 6 ┆ a │ │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ │ 4 ┆ 9 ┆ d │ └─────┴─────┴─────┘
- property width: int[source]
获取列数。
- Returns:
- int
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [4, 5, 6], ... } ... ) >>> df.width 2
- with_columns(
- *exprs: IntoExpr | Iterable[IntoExpr],
- **named_exprs: IntoExpr,
向此DataFrame添加列。
添加的列将替换具有相同名称的现有列。
- Parameters:
- *exprs
要添加的列,指定为位置参数。 接受表达式输入。字符串被解析为列名,其他非表达式输入被解析为字面量。
- **named_exprs
要添加的额外列,指定为关键字参数。 这些列将被重命名为所使用的关键字。
- Returns:
- DataFrame
添加列后的新DataFrame。
注释
使用此方法创建新的DataFrame不会创建现有数据的新副本。
示例
传递一个表达式以将其添加为新列。
>>> df = pl.DataFrame( ... { ... "a": [1, 2, 3, 4], ... "b": [0.5, 4, 10, 13], ... "c": [True, True, False, True], ... } ... ) >>> df.with_columns((pl.col("a") ** 2).alias("a^2")) shape: (4, 4) ┌─────┬──────┬───────┬─────┐ │ a ┆ b ┆ c ┆ a^2 │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ bool ┆ i64 │ ╞═════╪══════╪═══════╪═════╡ │ 1 ┆ 0.5 ┆ true ┆ 1 │ │ 2 ┆ 4.0 ┆ true ┆ 4 │ │ 3 ┆ 10.0 ┆ false ┆ 9 │ │ 4 ┆ 13.0 ┆ true ┆ 16 │ └─────┴──────┴───────┴─────┘
添加的列将替换具有相同名称的现有列。
>>> df.with_columns(pl.col("a").cast(pl.Float64)) shape: (4, 3) ┌─────┬──────┬───────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ f64 ┆ f64 ┆ bool │ ╞═════╪══════╪═══════╡ │ 1.0 ┆ 0.5 ┆ true │ │ 2.0 ┆ 4.0 ┆ true │ │ 3.0 ┆ 10.0 ┆ false │ │ 4.0 ┆ 13.0 ┆ true │ └─────┴──────┴───────┘
可以使用位置参数添加多列。
>>> df.with_columns( ... (pl.col("a") ** 2).alias("a^2"), ... (pl.col("b") / 2).alias("b/2"), ... (pl.col("c").not_()).alias("not c"), ... ) shape: (4, 6) ┌─────┬──────┬───────┬─────┬──────┬───────┐ │ a ┆ b ┆ c ┆ a^2 ┆ b/2 ┆ not c │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ bool ┆ i64 ┆ f64 ┆ bool │ ╞═════╪══════╪═══════╪═════╪══════╪═══════╡ │ 1 ┆ 0.5 ┆ true ┆ 1 ┆ 0.25 ┆ false │ │ 2 ┆ 4.0 ┆ true ┆ 4 ┆ 2.0 ┆ false │ │ 3 ┆ 10.0 ┆ false ┆ 9 ┆ 5.0 ┆ true │ │ 4 ┆ 13.0 ┆ true ┆ 16 ┆ 6.5 ┆ false │ └─────┴──────┴───────┴─────┴──────┴───────┘
也可以通过传递表达式列表来添加多个列。
>>> df.with_columns( ... [ ... (pl.col("a") ** 2).alias("a^2"), ... (pl.col("b") / 2).alias("b/2"), ... (pl.col("c").not_()).alias("not c"), ... ] ... ) shape: (4, 6) ┌─────┬──────┬───────┬─────┬──────┬───────┐ │ a ┆ b ┆ c ┆ a^2 ┆ b/2 ┆ not c │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ bool ┆ i64 ┆ f64 ┆ bool │ ╞═════╪══════╪═══════╪═════╪══════╪═══════╡ │ 1 ┆ 0.5 ┆ true ┆ 1 ┆ 0.25 ┆ false │ │ 2 ┆ 4.0 ┆ true ┆ 4 ┆ 2.0 ┆ false │ │ 3 ┆ 10.0 ┆ false ┆ 9 ┆ 5.0 ┆ true │ │ 4 ┆ 13.0 ┆ true ┆ 16 ┆ 6.5 ┆ false │ └─────┴──────┴───────┴─────┴──────┴───────┘
使用关键字参数可以轻松命名您的表达式输入。
>>> df.with_columns( ... ab=pl.col("a") * pl.col("b"), ... not_c=pl.col("c").not_(), ... ) shape: (4, 5) ┌─────┬──────┬───────┬──────┬───────┐ │ a ┆ b ┆ c ┆ ab ┆ not_c │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ bool ┆ f64 ┆ bool │ ╞═════╪══════╪═══════╪══════╪═══════╡ │ 1 ┆ 0.5 ┆ true ┆ 0.5 ┆ false │ │ 2 ┆ 4.0 ┆ true ┆ 8.0 ┆ false │ │ 3 ┆ 10.0 ┆ false ┆ 30.0 ┆ true │ │ 4 ┆ 13.0 ┆ true ┆ 52.0 ┆ false │ └─────┴──────┴───────┴──────┴───────┘
通过启用设置
Config.set_auto_structify(True),可以将具有多个输出的表达式自动实例化为结构体:>>> with pl.Config(auto_structify=True): ... df.drop("c").with_columns( ... diffs=pl.col(["a", "b"]).diff().name.suffix("_diff"), ... ) shape: (4, 3) ┌─────┬──────┬─────────────┐ │ a ┆ b ┆ diffs │ │ --- ┆ --- ┆ --- │ │ i64 ┆ f64 ┆ struct[2] │ ╞═════╪══════╪═════════════╡ │ 1 ┆ 0.5 ┆ {null,null} │ │ 2 ┆ 4.0 ┆ {1,3.5} │ │ 3 ┆ 10.0 ┆ {1,6.0} │ │ 4 ┆ 13.0 ┆ {1,3.0} │ └─────┴──────┴─────────────┘
- with_columns_seq(
- *exprs: IntoExpr | Iterable[IntoExpr],
- **named_exprs: IntoExpr,
向此DataFrame添加列。
添加的列将替换具有相同名称的现有列。
这将按顺序运行所有表达式,而不是并行运行。当每个表达式的工作量较小时使用此方法。
- Parameters:
- *exprs
要添加的列,指定为位置参数。 接受表达式输入。字符串被解析为列名,其他非表达式输入被解析为字面量。
- **named_exprs
要添加的额外列,指定为关键字参数。 这些列将被重命名为所使用的关键字。
- Returns:
- DataFrame
添加列后的新DataFrame。
另请参阅
- with_row_count( ) DataFrame[source]
在第0列添加一个用于计算行数的列。
自版本0.20.4起已弃用:请改用
with_row_index()。 请注意,默认列名已从‘row_nr’更改为‘index’。- Parameters:
- name
要添加的列的名称。
- offset
从这个偏移量开始行计数。默认值 = 0
示例
>>> df = pl.DataFrame( ... { ... "a": [1, 3, 5], ... "b": [2, 4, 6], ... } ... ) >>> df.with_row_count() shape: (3, 3) ┌────────┬─────┬─────┐ │ row_nr ┆ a ┆ b │ │ --- ┆ --- ┆ --- │ │ u32 ┆ i64 ┆ i64 │ ╞════════╪═════╪═════╡ │ 0 ┆ 1 ┆ 2 │ │ 1 ┆ 3 ┆ 4 │ │ 2 ┆ 5 ┆ 6 │ └────────┴─────┴─────┘
- with_row_index( ) DataFrame[source]
在DataFrame中添加一行索引作为第一列。
- Parameters:
- name
索引列的名称。
- offset
从这个偏移量开始索引。不能为负数。
注释
生成的列没有任何特殊属性。它是一个常规的列,类型为
UInt32(或在polars-u64-idx中为UInt64)。示例
>>> df = pl.DataFrame( ... { ... "a": [1, 3, 5], ... "b": [2, 4, 6], ... } ... ) >>> df.with_row_index() shape: (3, 3) ┌───────┬─────┬─────┐ │ index ┆ a ┆ b │ │ --- ┆ --- ┆ --- │ │ u32 ┆ i64 ┆ i64 │ ╞═══════╪═════╪═════╡ │ 0 ┆ 1 ┆ 2 │ │ 1 ┆ 3 ┆ 4 │ │ 2 ┆ 5 ┆ 6 │ └───────┴─────┴─────┘ >>> df.with_row_index("id", offset=1000) shape: (3, 3) ┌──────┬─────┬─────┐ │ id ┆ a ┆ b │ │ --- ┆ --- ┆ --- │ │ u32 ┆ i64 ┆ i64 │ ╞══════╪═════╪═════╡ │ 1000 ┆ 1 ┆ 2 │ │ 1001 ┆ 3 ┆ 4 │ │ 1002 ┆ 5 ┆ 6 │ └──────┴─────┴─────┘
索引列也可以使用表达式
int_range()和len()创建。>>> df.select( ... pl.int_range(pl.len(), dtype=pl.UInt32).alias("index"), ... pl.all(), ... ) shape: (3, 3) ┌───────┬─────┬─────┐ │ index ┆ a ┆ b │ │ --- ┆ --- ┆ --- │ │ u32 ┆ i64 ┆ i64 │ ╞═══════╪═════╪═════╡ │ 0 ┆ 1 ┆ 2 │ │ 1 ┆ 3 ┆ 4 │ │ 2 ┆ 5 ┆ 6 │ └───────┴─────┴─────┘
- write_avro( ) None[source]
写入Apache Avro文件。
- Parameters:
- file
文件路径或可写入的文件类对象,数据将被写入其中。
- compression{‘uncompressed’, ‘snappy’, ‘deflate’}
压缩方法。默认为“未压缩”。
- name
模式名称。默认为空字符串。
示例
>>> import pathlib >>> >>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> path: pathlib.Path = dirpath / "new_file.avro" >>> df.write_avro(path)
- write_clipboard(*, separator: str = '\t', **kwargs: Any) None[source]
将
DataFrame以csv格式复制到系统剪贴板,使用write_csv。适用于粘贴到Excel或其他类似的电子表格软件中。
- Parameters:
- separator
用此符号分隔CSV字段。
- kwargs
传递给
write_csv的额外参数。
另请参阅
polars.read_clipboard从剪贴板读取一个DataFrame。
write_csv写入逗号分隔值(CSV)文件。
- write_csv(
- file: str | Path | IO[str] | IO[bytes] | None = None,
- *,
- include_bom: bool = False,
- include_header: bool = True,
- separator: str = ',',
- line_terminator: str = '\n',
- quote_char: str = '"',
- batch_size: int = 1024,
- datetime_format: str | None = None,
- date_format: str | None = None,
- time_format: str | None = None,
- float_scientific: bool | None = None,
- float_precision: int | None = None,
- null_value: str | None = None,
- quote_style: CsvQuoteStyle | None = None,
- storage_options: dict[str, Any] | None = None,
- credential_provider: CredentialProviderFunction | Literal['auto'] | None = 'auto',
- retries: int = 2,
写入逗号分隔值(CSV)文件。
- Parameters:
- file
文件路径或可写的类文件对象,结果将被写入其中。 如果设置为
None(默认值),则输出将作为字符串返回。- include_bom
是否在CSV输出中包含UTF-8 BOM。
- include_header
是否在CSV输出中包含标题。
- separator
用此符号分隔CSV字段。
- line_terminator
用于结束每一行的字符串。
- quote_char
用作引用字符的字节。
- batch_size
每个线程将处理的行数。
- datetime_format
一个格式字符串,使用由 chrono Rust crate 定义的说明符。如果未指定格式,则默认的分数秒精度将从帧的Datetime列中找到的最大时间单位推断(如果有的话)。
- date_format
一个格式字符串,使用由 chrono Rust crate 定义的说明符。
- time_format
一个格式字符串,使用由 chrono Rust crate 定义的说明符。
- float_scientific
是否始终使用科学计数法(true),从不使用(false),或自动选择(None)用于
Float32和Float64数据类型。- float_precision
要写入的小数位数,适用于
Float32和Float64数据类型。- null_value
表示空值的字符串(默认为空字符串)。
- quote_style{‘necessary’, ‘always’, ‘non_numeric’, ‘never’}
确定使用的引用策略。
必要的(默认):仅在必要时在字段周围加上引号。当字段包含引号、分隔符或记录终止符时,引号是必要的。在写入空记录时(这与具有一个空字段的记录无法区分),引号也是必要的。这是默认设置。
always: 这会在每个字段周围加上引号。总是如此。
never: 这永远不会在字段周围加上引号,即使这会导致无效的CSV数据(例如:不引用包含分隔符的字符串)。
non_numeric: 这会在所有非数字字段周围加上引号。 也就是说,当写入一个无法解析为有效浮点数 或整数的字段时,即使严格来说不需要,也会使用引号。
- storage_options
指示如何连接到云提供商的选项。
目前支持的云提供商有AWS、GCP和Azure。 查看支持的密钥请点击这里:
如果未提供
storage_options,Polars将尝试从环境变量中推断信息。- credential_provider
提供一个可以被调用的函数来提供云存储凭证。该函数预期返回一个包含凭证键的字典以及一个可选的凭证过期时间。
警告
此功能被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
- retries
如果访问云实例失败,重试次数。
示例
>>> import pathlib >>> >>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> path: pathlib.Path = dirpath / "new_file.csv" >>> df.write_csv(path, separator=",")
- write_database(
- table_name: str,
- connection: ConnectionOrCursor | str,
- *,
- if_table_exists: DbWriteMode = 'fail',
- engine: DbWriteEngine | None = None,
- engine_options: dict[str, Any] | None = None,
将Polars DataFrame中的数据写入数据库。
在版本0.20.26中添加:除了URI字符串外,还支持实例化的连接对象,以及一个新的
engine_options参数。- Parameters:
- table_name
目标SQL数据库中要创建或追加的表的模式限定名称。如果您的表名包含特殊字符,则应使用引号括起来。
- connection
一个针对目标数据库的现有SQLAlchemy或ADBC连接,或者将用于实例化此类连接的URI字符串,例如:
“postgresql://user:pass@server:port/database”
“sqlite:////path/to/database.db”
- if_table_exists{‘append’, ‘replace’, ‘fail’}
插入模式:
'replace' 将创建一个新的数据库表,覆盖现有的表。
'append' 将会附加到现有的表中。
如果表已经存在,‘fail’将会失败。
- engine{‘sqlalchemy’, ‘adbc’}
选择用于写入帧数据的引擎;仅在提供URI字符串时需要(如果未设置,则默认为‘sqlalchemy’)
- engine_options
传递给与由选项
engine指定的引擎相关联的插入方法的附加选项。将
engine设置为“sqlalchemy”目前使用Pandas的to_sql方法进行插入(尽管这最终将被原生解决方案所取代)。将
engine设置为 "adbc" 时,使用 ADBC 光标的adbc_ingest方法进行插入。
- Returns:
- int
受影响的行数,如果驱动程序提供此信息。 否则,返回-1。
示例
使用PostgreSQL URI和ADBC引擎插入到临时表中:
>>> df.write_database( ... table_name="target_table", ... connection="postgresql://user:pass@server:port/database", ... engine="adbc", ... engine_options={"temporary": True}, ... )
使用
pyodbcSQLAlchemy 连接到 SQL Server 并插入到表中,该连接实例化时使用了“fast_executemany=True”以提高性能:>>> pyodbc_uri = ( ... "mssql+pyodbc://user:pass@server:1433/test?" ... "driver=ODBC+Driver+18+for+SQL+Server" ... ) >>> engine = create_engine(pyodbc_uri, fast_executemany=True) >>> df.write_database( ... table_name="target_table", ... connection=engine, ... )
- write_delta(
- target: str | Path | deltalake.DeltaTable,
- *,
- mode: Literal['error', 'append', 'overwrite', 'ignore', 'merge'] = 'error',
- overwrite_schema: bool | None = None,
- storage_options: dict[str, str] | None = None,
- delta_write_options: dict[str, Any] | None = None,
- delta_merge_options: dict[str, Any] | None = None,
将DataFrame写入为delta表。
- Parameters:
- target
表或DeltaTable对象的URI。
- mode{‘error’, ‘append’, ‘overwrite’, ‘ignore’, ‘merge’}
如何处理现有数据。
如果 'error',当表已经存在时抛出错误(默认)。
如果选择‘append’,将会添加新数据。
如果选择‘overwrite’,将用新数据替换表格。
如果选择‘ignore’,当表已经存在时,将不会写入任何内容。
如果选择‘merge’,则返回一个
TableMerger对象,用于将DataFrame中的数据与现有数据合并。
- overwrite_schema
如果为True,允许更新表的模式。
自版本0.20.14起已弃用:请改用参数
delta_write_options并传递{"schema_mode": "overwrite"}。- storage_options
为
deltalake支持的存储后端提供的额外选项。 对于云存储,这可能包括认证等的配置。- delta_write_options
写入Delta Lake表时的额外关键字参数。 查看支持的写入选项列表这里。
- delta_merge_options
用于
MERGEDelta Lake 表所需的关键字参数。 查看支持的合并选项列表 这里。
- Raises:
- TypeError
如果DataFrame包含不支持的数据类型。
- ArrowInvalidError
如果DataFrame包含无法转换为其原始类型的数据类型。
- TableNotFoundError
如果delta表不存在并且触发了MERGE操作
注释
Polars 数据类型
Null和Time不受 delta 协议规范支持,并且会引发 TypeError。使用Categorical数据类型的列在写入时将被转换为普通(非分类)字符串。Polars 列始终可为空。要将数据写入具有非空列的 delta 表,必须将自定义的 pyarrow 模式传递给
delta_write_options。请参阅下面的最后一个示例。示例
将数据框写入本地文件系统作为Delta Lake表。
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> table_path = "/path/to/delta-table/" >>> df.write_delta(table_path)
将数据追加到本地文件系统上现有的Delta Lake表中。 请注意,如果新数据的模式与现有表的模式不匹配,此操作将失败。
>>> df.write_delta(table_path, mode="append")
覆盖Delta Lake表为新版本。 如果新旧数据的模式相同,则不需要指定
schema_mode。>>> existing_table_path = "/path/to/delta-table/" >>> df.write_delta( ... existing_table_path, ... mode="overwrite", ... delta_write_options={"schema_mode": "overwrite"}, ... )
将DataFrame作为Delta Lake表写入云对象存储,如S3。
>>> table_path = "s3://bucket/prefix/to/delta-table/" >>> df.write_delta( ... table_path, ... storage_options={ ... "AWS_REGION": "THE_AWS_REGION", ... "AWS_ACCESS_KEY_ID": "THE_AWS_ACCESS_KEY_ID", ... "AWS_SECRET_ACCESS_KEY": "THE_AWS_SECRET_ACCESS_KEY", ... }, ... )
将DataFrame写入为具有非空列的Delta Lake表。
>>> import pyarrow as pa >>> existing_table_path = "/path/to/delta-table/" >>> df.write_delta( ... existing_table_path, ... delta_write_options={ ... "schema": pa.schema([pa.field("foo", pa.int64(), nullable=False)]) ... }, ... )
将DataFrame与现有的Delta Lake表合并。 对于所有
TableMerger方法,请查看deltalake文档 这里。>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> table_path = "/path/to/delta-table/" >>> ( ... df.write_delta( ... "table_path", ... mode="merge", ... delta_merge_options={ ... "predicate": "s.foo = t.foo", ... "source_alias": "s", ... "target_alias": "t", ... }, ... ) ... .when_matched_update_all() ... .when_not_matched_insert_all() ... .execute() ... )
- write_excel(
- workbook: str | Workbook | IO[bytes] | Path | None = None,
- worksheet: str | Worksheet | None = None,
- *,
- position: tuple[int, int] | str = 'A1',
- table_style: str | dict[str, Any] | None = None,
- table_name: str | None = None,
- column_formats: ColumnFormatDict | None = None,
- dtype_formats: dict[OneOrMoreDataTypes, str] | None = None,
- conditional_formats: ConditionalFormatDict | None = None,
- header_format: dict[str, Any] | None = None,
- column_totals: ColumnTotalsDefinition | None = None,
- column_widths: ColumnWidthsDefinition | None = None,
- row_totals: RowTotalsDefinition | None = None,
- row_heights: dict[int | tuple[int, ...], int] | int | None = None,
- sparklines: dict[str, Sequence[str] | dict[str, Any]] | None = None,
- formulas: dict[str, str | dict[str, str]] | None = None,
- float_precision: int = 3,
- include_header: bool = True,
- autofilter: bool = True,
- autofit: bool = False,
- hidden_columns: Sequence[str] | SelectorType | None = None,
- hide_gridlines: bool = False,
- sheet_zoom: int | None = None,
- freeze_panes: str | tuple[int, int] | tuple[str, int, int] | tuple[int, int, int, int] | None = None,
将框架数据写入Excel工作簿/工作表中的表格。
- Parameters:
- workbook{str, Workbook}
要创建的工作簿的字符串名称或路径,要写入的BytesIO对象,或未关闭的
xlsxwriter.Workbook对象。如果为None,则写入工作目录中的dataframe.xlsx工作簿。- worksheet{str, Worksheet}
目标工作表的名称或一个
xlsxwriter.Worksheet对象(在这种情况下,workbook必须是父xlsxwriter.Workbook对象);如果为None,则在创建新工作簿时写入“Sheet1”(注意,写入现有工作簿需要有效的现有或新工作表名称)。- position{str, tuple}
Excel 表示法中的表格位置(例如:“A1”),或一个 (行,列) 的整数元组。
- table_style{str, dict}
一个命名的Excel表格样式,例如“表格样式中等4”,或者一个包含以下一个或多个键的
{"key":value,}选项的字典: “style”,“first_column”,“last_column”,“banded_columns”,“banded_rows”。- table_namestr
工作表中输出表对象的名称;然后可以通过公式/图表或后续的
xlsxwriter操作在工作表中引用。- column_formatsdict
一个
{colname(s):str,}或{selector:str,}字典,用于将Excel格式字符串应用于给定的列。此处定义的格式(如“dd/mm/yyyy”、“0.00%”等)将覆盖dtype_formats中定义的任何格式。- dtype_formatsdict
一个
{dtype:str,}字典,用于设置给定数据类型的默认Excel格式。(这可以通过column_formats参数在每列基础上进行覆盖)。- conditional_formatsdict
一个以列名(或选择器)为键的字典,其值为格式字符串、字典或列表,用于定义指定列的条件格式选项。
如果提供字符串类型名称,应该是有效的
xlsxwriter类型之一,例如“3_color_scale”、“data_bar”等。如果提供字典,你可以使用任何/所有
xlsxwriter支持的选项,包括图标集、公式等。将多个列作为元组/键提供将在所有列上应用单一格式 - 这在创建热图时非常有效,因为最小/最大值将在整个范围内确定,而不是每列单独确定。
最后,您还可以提供一个由上述选项组成的列表,以便对同一范围应用多个条件格式。
- header_formatdict
一个
{key:value,}字典,包含要应用于表头行的xlsxwriter格式选项,例如{"bold":True, "font_color":"#702963"}。- column_totals{bool, list, dict}
在导出的表格中添加一个列总计行。
如果为True,所有数值列将使用“sum”关联一个总计。
如果传递一个字符串,它必须是有效的总计函数名称之一,并且所有数值列都将使用该函数关联一个总计。
如果传递一个列名列表,只有给定的列才会有总计。
为了更多的控制,传递一个
{colname:funcname,}字典。
有效的列总计函数名称是“average”、“count_nums”、“count”、“max”、“min”、“std_dev”、“sum”和“var”。
- column_widths{dict, int}
一个
{colname:int,}或{selector:int,}字典或单个整数,用于设置(或如果自动调整则覆盖)表格列的宽度,单位为整数像素。如果给定为整数,则所有表格列使用相同的值。- row_totals{dict, list, bool}
在导出的表格右侧添加一行总计列。
如果为True,将在表格末尾添加一个名为“total”的列,该列将对所有数值列应用“sum”函数进行行求和。
如果传递列名的列表/序列,则只有匹配的列将参与求和。
也可以传递一个
{colname:columns,}字典来创建一个或多个具有不同名称的总列,引用不同的列。
- row_heights{dict, int}
一个整数或
{row_index:int,}字典,用于设置给定行(如果提供字典)或所有行(如果提供整数)的高度,这些行与表格主体(包括任何标题行和总计行)相交,单位为整数像素。请注意,row_index从零开始,并且将是标题行(除非include_header为False)。- sparklinesdict
一个
{colname:list,}或{colname:dict,}字典,用于定义一个或多个要写入表格新列中的迷你图。如果传递列名列表(用作迷你图数据的来源),则使用默认的迷你图设置(例如:没有标记的折线图)。
为了更多的控制,可以提供一个符合
xlsxwriter的选项字典, 在这种情况下,有三个额外的polars特定键可用: “columns”、“insert_before”和“insert_after”。这些允许你定义 源列并根据其他表格列的位置来放置迷你图。如果没有给出位置指令,迷你图将按照给定的顺序添加到表格的末尾(例如:最右边)。
- formulasdict
一个
{colname:formula,}或{colname:dict,}字典,用于定义一个或多个公式,这些公式将被写入表格中的新列。请注意,强烈建议在公式中尽可能使用结构化引用,以便通过名称简单引用列。如果提供一个字符串公式(例如“=[@colx]*[@coly]”),该列将被添加到表格的末尾(例如:最右边),在任何默认的迷你图之后,并在任何行总计之前。
为了获得最大的控制权,请提供一个包含以下键的选项字典: “formula”(必填),“insert_before”或“insert_after”中的一个,以及 可选的“return_dtype”。后者用于适当地格式化 公式的输出,并允许其参与行/列总计。
- float_precisionint
浮点数列显示的默认小数位数(请注意,这纯粹是一个格式化指令;实际值不会被四舍五入)。
- include_headerbool
指示是否应创建带有标题行的表格。
- autofilterbool
如果表格有标题,提供自动筛选功能。
- autofitbool
从数据中计算各列的宽度。
- hidden_columnsstr | list
列名、列名列表或表示表格列的selector,用于在输出工作表中标记为隐藏。
- hide_gridlinesbool
不要在输出工作表上显示任何网格线。
- sheet_zoomint
设置输出工作表的默认缩放级别。
- freeze_panesstr | (str, int, int) | (int, int) | (int, int, int, int)
冻结工作表的窗格。
如果提供了 (row, col),窗格将在指定单元格的左上角分割,这些单元格是从0开始索引的。因此,要仅冻结顶部行,请提供 (1, 0)。
或者,可以使用单元格表示法来提供单元格。例如,“A2”表示分割发生在单元格A2的左上角,这相当于(1, 0)。
如果提供了 (row, col, top_row, top_col),则根据
row和col来分割窗格,并且滚动区域初始化为从top_row和top_col开始。因此,要仅冻结顶部行并使滚动区域从第10行、D列(第5列)开始,请提供 (1, 0, 9, 4)。使用单元格表示法 (row, col),提供 (“A2”, 9, 4) 是等效的。
注释
兼容的
xlsxwriter格式属性名称列表可以在这里找到: https://xlsxwriter.readthedocs.io/format.html#format-methods-and-format-properties条件格式字典应提供与xlsxwriter兼容的定义;polars将负责如何根据相对工作表/列位置在工作表上应用它们。有关支持的选项,请参阅:https://xlsxwriter.readthedocs.io/working_with_conditional_formats.html
同样,迷你图选项字典应包含与xlsxwriter兼容的键/值,以及一个必需的polars“columns”键,用于定义迷你图的源数据;这些源列应全部相邻。另外两个polars特定的键可用于帮助定义迷你图在表格中的显示位置:“insert_after”和“insert_before”。与这些键关联的值应为导出表格中列的名称。 https://xlsxwriter.readthedocs.io/working_with_sparklines.html
公式字典必须包含一个名为“formula”的键,然后是可选的“insert_after”、“insert_before”和/或“return_dtype”键。这些额外的键允许将列注入到表格中的特定位置,和/或定义公式的返回类型(例如:“Int64”、“Float64”等)。引用表格列的公式应使用Excel的结构化引用语法,以确保公式正确应用并与表格相关。https://support.microsoft.com/en-us/office/using-structured-references-with-excel-tables-f5ed2452-2337-4f71-bed3-c8ae6d2b276e
示例
实例化一个基本的DataFrame:
>>> from random import uniform >>> from datetime import date >>> >>> df = pl.DataFrame( ... { ... "dtm": [date(2023, 1, 1), date(2023, 1, 2), date(2023, 1, 3)], ... "num": [uniform(-500, 500), uniform(-500, 500), uniform(-500, 500)], ... "val": [10_000, 20_000, 30_000], ... } ... )
导出到工作目录中的“dataframe.xlsx”(如果未指定,则为默认工作簿名称),在所有数值列上添加列总计(默认为“sum”),然后自动调整:
>>> df.write_excel(column_totals=True, autofit=True)
将框架写入工作表的特定位置,设置一个命名的表格样式, 应用美式日期格式,增加默认的浮点数精度,对单个列应用非默认的总计函数,自动调整:
>>> df.write_excel( ... position="B4", ... table_style="Table Style Light 16", ... dtype_formats={pl.Date: "mm/dd/yyyy"}, ... column_totals={"num": "average"}, ... float_precision=6, ... autofit=True, ... )
将相同的框架写入命名的工作表两次,对每个表格应用不同的样式和条件格式,使用显式的xlsxwriter集成添加表格标题:
>>> from xlsxwriter import Workbook >>> with Workbook("multi_frame.xlsx") as wb: ... # basic/default conditional formatting ... df.write_excel( ... workbook=wb, ... worksheet="data", ... position=(3, 1), # specify position as (row,col) coordinates ... conditional_formats={"num": "3_color_scale", "val": "data_bar"}, ... table_style="Table Style Medium 4", ... ) ... ... # advanced conditional formatting, custom styles ... df.write_excel( ... workbook=wb, ... worksheet="data", ... position=(len(df) + 7, 1), ... table_style={ ... "style": "Table Style Light 4", ... "first_column": True, ... }, ... conditional_formats={ ... "num": { ... "type": "3_color_scale", ... "min_color": "#76933c", ... "mid_color": "#c4d79b", ... "max_color": "#ebf1de", ... }, ... "val": { ... "type": "data_bar", ... "data_bar_2010": True, ... "bar_color": "#9bbb59", ... "bar_negative_color_same": True, ... "bar_negative_border_color_same": True, ... }, ... }, ... column_formats={"num": "#,##0.000;[White]-#,##0.000"}, ... column_widths={"val": 125}, ... autofit=True, ... ) ... ... # add some table titles (with a custom format) ... ws = wb.get_worksheet_by_name("data") ... fmt_title = wb.add_format( ... { ... "font_color": "#4f6228", ... "font_size": 12, ... "italic": True, ... "bold": True, ... } ... ) ... ws.write(2, 1, "Basic/default conditional formatting", fmt_title) ... ws.write(len(df) + 6, 1, "Customised conditional formatting", fmt_title)
导出一个包含两种不同类型迷你图的表格。对于“趋势”迷你图使用默认选项,对于“+/-”胜负迷你图使用自定义选项(和定位),包括非默认的整数数据类型格式化、列总计、微妙的双色调热图和隐藏的工作表网格线:
>>> df = pl.DataFrame( ... { ... "id": ["aaa", "bbb", "ccc", "ddd", "eee"], ... "q1": [100, 55, -20, 0, 35], ... "q2": [30, -10, 15, 60, 20], ... "q3": [-50, 0, 40, 80, 80], ... "q4": [75, 55, 25, -10, -55], ... } ... ) >>> df.write_excel( ... table_style="Table Style Light 2", ... # apply accounting format to all flavours of integer ... dtype_formats={dt: "#,##0_);(#,##0)" for dt in [pl.Int32, pl.Int64]}, ... sparklines={ ... # default options; just provide source cols ... "trend": ["q1", "q2", "q3", "q4"], ... # customized sparkline type, with positioning directive ... "+/-": { ... "columns": ["q1", "q2", "q3", "q4"], ... "insert_after": "id", ... "type": "win_loss", ... }, ... }, ... conditional_formats={ ... # create a unified multi-column heatmap ... ("q1", "q2", "q3", "q4"): { ... "type": "2_color_scale", ... "min_color": "#95b3d7", ... "max_color": "#ffffff", ... }, ... }, ... column_totals=["q1", "q2", "q3", "q4"], ... row_totals=True, ... hide_gridlines=True, ... )
导出一个包含基于Excel公式的列的表,该列计算标准化的Z分数,展示了结构化引用与定位指令、列总计和自定义格式的结合使用。
>>> df = pl.DataFrame( ... { ... "id": ["a123", "b345", "c567", "d789", "e101"], ... "points": [99, 45, 50, 85, 35], ... } ... ) >>> df.write_excel( ... table_style={ ... "style": "Table Style Medium 15", ... "first_column": True, ... }, ... column_formats={ ... "id": {"font": "Consolas"}, ... "points": {"align": "center"}, ... "z-score": {"align": "center"}, ... }, ... column_totals="average", ... formulas={ ... "z-score": { ... # use structured references to refer to the table columns and 'totals' row ... "formula": "=STANDARDIZE([@points], [[#Totals],[points]], STDEV([points]))", ... "insert_after": "points", ... "return_dtype": pl.Float64, ... } ... }, ... hide_gridlines=True, ... sheet_zoom=125, ... )
直接创建并引用一个Worksheet对象,添加一个基本图表。 强烈建议利用结构化引用来设置图表系列值和类别,这样您就不必计算相对于框架数据和工作表的单元格位置:
>>> with Workbook("basic_chart.xlsx") as wb: ... # create worksheet object and write frame data to it ... ws = wb.add_worksheet("demo") ... df.write_excel( ... workbook=wb, ... worksheet=ws, ... table_name="DataTable", ... table_style="Table Style Medium 26", ... hide_gridlines=True, ... ) ... # create chart object, point to the written table ... # data using structured references, and style it ... chart = wb.add_chart({"type": "column"}) ... chart.set_title({"name": "Example Chart"}) ... chart.set_legend({"none": True}) ... chart.set_style(38) ... chart.add_series( ... { # note the use of structured references ... "values": "=DataTable[points]", ... "categories": "=DataTable[id]", ... "data_labels": {"value": True}, ... } ... ) ... # add chart to the worksheet ... ws.insert_chart("D1", chart)
- write_ipc(
- file: str | Path | IO[bytes] | None,
- *,
- compression: IpcCompression = 'uncompressed',
- compat_level: CompatLevel | None = None,
- storage_options: dict[str, Any] | None = None,
- credential_provider: CredentialProviderFunction | Literal['auto'] | None = 'auto',
- retries: int = 2,
写入Arrow IPC二进制流或Feather文件。
请参阅https://arrow.apache.org/docs/python/ipc.html中的“文件或随机访问格式”。
- Parameters:
- file
路径或可写的类文件对象,IPC数据将被写入其中。如果设置为
None,输出将作为BytesIO对象返回。- compression{‘uncompressed’, ‘lz4’, ‘zstd’}
压缩方法。默认为“未压缩”。
- compat_level
在导出Polars的内部数据结构时使用特定的兼容性级别。
- storage_options
指示如何连接到云提供商的选项。
目前支持的云提供商有AWS、GCP和Azure。 查看支持的密钥请点击这里:
如果未提供
storage_options,Polars将尝试从环境变量中推断信息。- credential_provider
提供一个可以被调用的函数来提供云存储凭证。该函数预期返回一个包含凭证键的字典以及一个可选的凭证过期时间。
警告
此功能被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
- retries
如果访问云实例失败,重试次数。
示例
>>> import pathlib >>> >>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> path: pathlib.Path = dirpath / "new_file.arrow" >>> df.write_ipc(path)
- write_ipc_stream(
- file: str | Path | IO[bytes] | None,
- *,
- compression: IpcCompression = 'uncompressed',
- compat_level: CompatLevel | None = None,
写入Arrow IPC记录批次流。
请参阅https://arrow.apache.org/docs/python/ipc.html中的“流式格式”。
- Parameters:
- file
路径或可写的类文件对象,IPC记录批处理数据将被写入其中。如果设置为
None,则输出将作为BytesIO对象返回。- compression{‘uncompressed’, ‘lz4’, ‘zstd’}
压缩方法。默认为“未压缩”。
- compat_level
在导出Polars的内部数据结构时使用特定的兼容性级别。
示例
>>> import pathlib >>> >>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> path: pathlib.Path = dirpath / "new_file.arrow" >>> df.write_ipc_stream(path)
- write_json(file: IOBase | str | Path | None = None) str | None[source]
序列化为JSON表示。
- Parameters:
- file
文件路径或可写的类文件对象,结果将被写入其中。 如果设置为
None(默认值),则输出将作为字符串返回。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... } ... ) >>> df.write_json() '[{"foo":1,"bar":6},{"foo":2,"bar":7},{"foo":3,"bar":8}]'
- write_ndjson(file: IOBase | str | Path | None = None) str | None[source]
序列化为换行符分隔的JSON表示。
- Parameters:
- file
文件路径或可写的类文件对象,结果将被写入其中。 如果设置为
None(默认值),则输出将作为字符串返回。
示例
>>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3], ... "bar": [6, 7, 8], ... } ... ) >>> df.write_ndjson() '{"foo":1,"bar":6}\n{"foo":2,"bar":7}\n{"foo":3,"bar":8}\n'
- write_parquet(
- file: str | Path | IO[bytes],
- *,
- compression: ParquetCompression = 'zstd',
- compression_level: int | None = None,
- statistics: bool | str | dict[str, bool] = True,
- row_group_size: int | None = None,
- data_page_size: int | None = None,
- use_pyarrow: bool = False,
- pyarrow_options: dict[str, Any] | None = None,
- partition_by: str | Sequence[str] | None = None,
- partition_chunk_size_bytes: int = 4294967296,
- storage_options: dict[str, Any] | None = None,
- credential_provider: CredentialProviderFunction | Literal['auto'] | None = 'auto',
- retries: int = 2,
写入Apache Parquet文件。
- Parameters:
- file
文件路径或可写的类文件对象,结果将被写入其中。 如果要写入分区数据集,这应该是一个目录的路径。
- compression{‘lz4’, ‘uncompressed’, ‘snappy’, ‘gzip’, ‘lzo’, ‘brotli’, ‘zstd’}
选择“zstd”以获得良好的压缩性能。 选择“lz4”以实现快速的压缩/解压缩。 选择“snappy”以在处理较旧的parquet读取器时获得更多的向后兼容性保证。
- compression_level
使用的压缩级别。更高的压缩意味着磁盘上的文件更小。
“gzip” : 最小级别: 0, 最大级别: 10.
“brotli”:最小级别:0,最大级别:11。
“zstd” : 最小级别: 1, 最大级别: 22.
- statistics
将统计信息写入parquet头部。这是默认行为。
可能的值:
True: 启用默认的统计集合(默认)False: 禁用所有统计信息“full”:计算并写入所有可用的统计信息。不能与
use_pyarrow结合使用。{ "statistic-key": True / False, ... }. 不能与use_pyarrow结合使用。可用的键:“min”: 列的最小值 (默认:
True)“max”: 列的最大值 (默认:
True)“distinct_count”: 唯一列值的数量(默认值:
False)“null_count”: 列中空值的数量(默认值:
True)
- row_group_size
行组的大小,以行数为单位。默认为512^2行。
- data_page_size
数据页的大小,以字节为单位。默认为1024^2字节。
- use_pyarrow
使用C++的parquet实现与Rust的parquet实现进行比较。 目前C++支持更多的功能。
- pyarrow_options
传递给
pyarrow.parquet.write_table的参数。如果你在这里传递
partition_cols,数据集将使用pyarrow.parquet.write_to_dataset进行写入。partition_cols参数会导致数据集被写入到一个目录中。 类似于Spark的分区数据集。- partition_by
用于分区的列。如果指定了此参数,将写入一个分区数据集。此参数被视为不稳定,可能会发生变化。
- partition_chunk_size_bytes
写入时单个分区内拆分DataFrame的近似大小。请注意,这是根据DataFrame在内存中的大小计算的 - 输出文件的大小可能会根据文件格式/压缩方式而有所不同。
- storage_options
指示如何连接到云提供商的选项。
目前支持的云提供商有AWS、GCP和Azure。 查看支持的密钥请点击这里:
如果未提供
storage_options,Polars将尝试从环境变量中推断信息。- credential_provider
提供一个可以被调用的函数来提供云存储凭证。该函数预期返回一个包含凭证键的字典以及一个可选的凭证过期时间。
警告
此功能被视为不稳定。它可能会在任何时候更改,而不被视为破坏性更改。
- retries
如果访问云实例失败,重试次数。
示例
>>> import pathlib >>> >>> df = pl.DataFrame( ... { ... "foo": [1, 2, 3, 4, 5], ... "bar": [6, 7, 8, 9, 10], ... "ham": ["a", "b", "c", "d", "e"], ... } ... ) >>> path: pathlib.Path = dirpath / "new_file.parquet" >>> df.write_parquet(path)
我们可以使用pyarrow并将use_pyarrow_write_to_dataset设置为True来写入分区数据集。以下示例将第一行写入../watermark=1/.parquet,其他行写入../watermark=2/.parquet。
>>> df = pl.DataFrame({"a": [1, 2, 3], "watermark": [1, 2, 2]}) >>> path: pathlib.Path = dirpath / "partitioned_object" >>> df.write_parquet( ... path, ... use_pyarrow=True, ... pyarrow_options={"partition_cols": ["watermark"]}, ... )