Polars简明基础教程九:Numpy和Pandas的相互转换(1)

到本讲座结束时,您将能够:

  •  在Polars和Numpy之间进行转换
  • 在Polars和Pandas之间进行转换 

此课程要求您的Pandas版本为1.5+,Polars版本为0.16.4+,PyArrow版本为11+。

你可以使用pl.show_versions()来检查您的安装情况

首先,我们还是以著名的“泰坦尼克号生还者数据集”作为例子(示例中用到的csv数据文件可在csdn 免费下载:“泰坦尼克号生还者数据集”):

import polars as pl
import numpy as np
import pandas as pd

csv_file = "../data/titanic.csv"
df = pl.read_csv(csv_file)
df.head(3)

shape: (3, 15)
┌──────────┬────────┬────────┬──────┬───┬──────┬─────────────┬───────┬───────┐
│ survived ┆ pclass ┆ sex    ┆ age  ┆ … ┆ deck ┆ embark_town ┆ alive ┆ alone │
│ ---      ┆ ---    ┆ ---    ┆ ---  ┆   ┆ ---  ┆ ---         ┆ ---   ┆ ---   │
│ i64      ┆ i64    ┆ str    ┆ f64  ┆   ┆ str  ┆ str         ┆ str   ┆ bool  │
╞══════════╪════════╪════════╪══════╪═══╪══════╪═════════════╪═══════╪═══════╡
│ 0        ┆ 3      ┆ male   ┆ 22.0 ┆ … ┆ null ┆ Southampton ┆ no    ┆ false │
│ 1        ┆ 1      ┆ female ┆ 38.0 ┆ … ┆ C    ┆ Cherbourg   ┆ yes   ┆ false │
│ 1        ┆ 3      ┆ female ┆ 26.0 ┆ … ┆ null ┆ Southampton ┆ yes   ┆ true  │
└──────────┴────────┴────────┴──────┴───┴──────┴─────────────┴───────┴───────┘

将DataFrame转换为Numpy

要将DataFrame转换为Numpy,请使用 to_numpy方法。这将克隆(复制)数据。

arr = df.to_numpy()

arr
[[0 3 'male' ... 'Southampton' 'no' False]
 [1 1 'female' ... 'Cherbourg' 'yes' False]
 [1 3 'female' ... 'Southampton' 'yes' True]
 ...
 [0 3 'female' ... 'Southampton' 'no' False]
 [1 1 'male' ... 'Cherbourg' 'yes' True]
 [0 3 'male' ... 'Queenstown' 'no' True]]

此转换将每一行转换为Numpy的ndarray,并将这些行数组垂直堆叠。

由于DataFrame具有混合类型,因此Numpy数组具有object数据类型。如果列具有统一的数值数据类型,则Numpy数组将具有相应的数据类型。

在此示例中,我们使用select来选择仅用于转换为Numpy的64位浮点列...

我们将在选择列和转换数据帧的部分中更详细地介绍select。

floats_array = (
    df
    .select(
        pl.col(pl.Float64)
    )
    .to_numpy()
)

floats_array
[[22.      7.25  ]
 [38.     71.2833]
 [26.      7.925 ]
 ...
 [    nan 23.45  ]
 [26.     30.    ]
 [32.      7.75  ]]

然后我们得到一个浮点Numpy数组

floats_array.dtype

float64

将Numpy转换为DataFrame

我们可以从Numpy数组创建一个Polars DataFrame

rand_array = np.random.standard_normal((5,3))
(
    pl.DataFrame(
        rand_array,
    )
)

shape: (5, 3)
┌───────────┬───────────┬───────────┐
│ column_0  ┆ column_1  ┆ column_2  │
│ ---       ┆ ---       ┆ ---       │
│ f64       ┆ f64       ┆ f64       │
╞═══════════╪═══════════╪═══════════╡
│ -0.360763 ┆ 1.320892  ┆ -0.280671 │
│ 1.849615  ┆ 0.664971  ┆ -0.382902 │
│ -1.112349 ┆ -1.426877 ┆ -3.624935 │
│ 0.222936  ┆ -0.467669 ┆ 1.280407  │
│ 0.897571  ┆ -1.312517 ┆ 1.650859  │
└───────────┴───────────┴───────────┘

如果我们想指定列名,可以可选地将列名列表传递给 pl.DataFrame。

如果我们有一个一维的Numpy数组,我们可以使用零拷贝的方式创建一个Polars Series或DataFrame。首先,我们创建一个全为1的一维数组

arr = np.ones(10)
arr.shape

(10,)

然后我们可以使用“零拷贝”的方式创建一个Series或DataFrame

使用零拷贝的方式创建一个Series

pl.Series("a", arr)

shape: (10,)
Series: 'a' [f64]
[
	1.0
	1.0
	1.0
	1.0
	1.0
	1.0
	1.0
	1.0
	1.0
	1.0
]

 使用零拷贝的方式创建一个 DataFrame

pl.DataFrame(
    {
       "a": arr,
    }
)

shape: (10, 1)
┌─────┐
│ a   │
│ --- │
│ f64 │
╞═════╡
│ 1.0 │
│ 1.0 │
│ 1.0 │
│ 1.0 │
│ 1.0 │
│ 1.0 │
│ 1.0 │
│ 1.0 │
│ 1.0 │
│ 1.0 │
└─────┘

零拷贝意味着数据(即全为1的数组)在内存中仅存储在一个位置。Numpy和Polars都在查看这个位置以获取原始Numpy数组或Polars Series或DataFrame的数据。

具体来说,当您将一个 NumPy 数组转换为 Polars 的 Series 或 DataFrame 时,“零拷贝”意味着 Polars 对象将不会创建数据的物理副本。相反,它会以一种方式引用或映射到原始 NumPy 数组的内存位置,以便能够直接访问这些数据。这样做的好处是减少了内存的使用,并可能提高了数据处理的效率,因为避免了不必要的数据复制。

将Series转换为Numpy

将Series转换为Numpy比将整个DataFrame转换具有更多选项。

要进行简单的转换,其中数据被克隆,请在Series上使用to_numpy

df['age'].head().to_numpy()

[22. 38. 26. 35. 35. nan 54.  2. 27. 14.]

使用零拷贝将Series转换为Numpy

在某些情况下,我们可以将Series转换为Numpy而无需复制(“零拷贝”)。

如果Series中没有null或NaN值(例如Survived列),则仅可能进行零拷贝。如果我们想确保转换为Numpy是零拷贝的,并且在需要复制时引发Exception,我们可以使用allow_copy参数

arr = (
    df['survived']
    .head()
    .to_numpy(allow_copy=False)
)

arr
[0 1 1 1 0 0 0 0 1 1]

如果我们尝试对包含null值的Age列使用这种零拷贝方法,我们将得到一个Exception

arr = (
    df['age']
    .head()
    .to_numpy(allow_copy=False)
)

arr

RuntimeError: copy not allowed: cannot convert to a NumPy array without copying data

在零拷贝转换中,Numpy数组是只读的,因此我们无法更改Numpy数组中的值。

在以下示例中,当我们尝试在Survived列上进行零拷贝操作后更改值时,会收到一个Exception

arr = (
    df['survived']
    .head()
    .to_numpy(allow_copy=False)
)

arr[0] = 100

ValueError: assignment destination is read-only

Polars简明基础教程系列

Polars简明基础教程一:Polars快速入门

Polars简明基础教程二:懒惰模式 1:引入懒惰模式

Polars简明基础教程三:懒惰模式 1:引入懒惰模式(续)

Polars简明基础教程四:懒惰模式 2:评估查询

Polars简明基础教程五:什么是Polars的“DataFrame(数据框)_上”

Polars简明基础教程六:什么是Polars的“DataFrame(数据框)_下”

Polars简明基础教程七:Series 和 DataFrame 以及它们之间的转换_A

Polars简明基础教程八:Series 和 DataFrame 以及它们之间的转换_B

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值