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

 将DataFrame转换为Pandas

转换为以Numpy为支持的Pandas DataFrame

Pandas历来使用Numpy数组来表示其在内存中的数据。

要将DataFrame转换为以Numpy数组为支持的Pandas DataFrame,请使用to_pandas方法。这与在上述DataFrame上调用to_numpy方法类似,会克隆数据。

注意:这种转换为Pandas的操作要求您已经通过pip或conda安装了PyArrow

(
    df
    .to_pandas()
    .head(2)
)

   survived  pclass     sex   age  ...  deck  embark_town  alive  alone
0         0       3    male  22.0  ...  None  Southampton     no  False
1         1       1  female  38.0  ...     C    Cherbourg    yes  False

[2 rows x 15 columns]

转换为以PyArrow为支持的Pandas DataFrame

自Pandas 1.5.0版本和Polars 1.6.4版本起,您可以使用以Arrow表为支持的Pandas DataFrame。您可以创建一个Pandas DataFrame,该DataFrame引用与您的Polars DataFrame相同的Arrow表。这意味着您可以在数据上使用(部分)Pandas代码,而无需复制数据。

(
    df
    .to_pandas(use_pyarrow_extension_array=True)
    .head(2)
)

   survived  pclass     sex   age  ...  deck  embark_town  alive  alone
0         0       3    male  22.0  ...  <NA>  Southampton     no  False
1         1       1  female  38.0  ...     C    Cherbourg    yes  False

[2 rows x 15 columns]

使用pyarrow扩展数组的优势在于,创建Pandas DataFrame的成本非常低,因为它不需要复制数据。

如果您想使用Pandas中的某个函数,您可以快速将其转换为Pandas,应用该函数,然后再转换回Polars。当然,这仅在急切模式下有效。

这种PyArrow转换是两个库中的新功能,因此在处理更复杂的功能(如分类或嵌套列)时可能会存在错误。

请注意,当您不使用PyArrow扩展方法时,Pandas中列的数据类型(dtypes)是标准的Pandas数据类型。当您使用PyArrow扩展方法时,Pandas中列的数据类型是PyArrow数据类型。

不使用PyArrow数据类型(dtypes)

这时意味着当将Polars的DataFrame转换为Pandas的DataFrame时,如果没有使用PyArrow作为底层支持,Pandas的DataFrame将使用其标准的数据类型(dtypes)来表示数据,而不是PyArrow的数据类型。这意味着数据类型可能会在转换过程中发生转换或调整,以适应Pandas的存储和表示方式。

df.to_pandas(use_pyarrow_extension_array=False).dtypes

survived         int64
pclass           int64
sex             object
age            float64
sibsp            int64
parch            int64
fare           float64
embarked        object
class           object
who             object
adult_male        bool
deck            object
embark_town     object
alive           object
alone             bool
dtype: object

使用PyArrow数据类型(dtypes)

df.to_pandas(use_pyarrow_extension_array=True).dtypes

survived              int64[pyarrow]
pclass                int64[pyarrow]
sex            large_string[pyarrow]
age                  double[pyarrow]
sibsp                 int64[pyarrow]
parch                 int64[pyarrow]
fare                 double[pyarrow]
embarked       large_string[pyarrow]
class          large_string[pyarrow]
who            large_string[pyarrow]
adult_male             bool[pyarrow]
deck           large_string[pyarrow]
embark_town    large_string[pyarrow]
alive          large_string[pyarrow]
alone                  bool[pyarrow]
dtype: object

在Polars的DataFrame上调用pd.DataFrame

在拥有最新版本的Pandas的情况下,您可以在Polars的DataFrame上调用pd.DataFrame

也就是说,如果您已经安装了最新版本的Pandas库,那么您可以直接在一个Polars的DataFrame对象上调用Pandas的DataFrame构造函数(即pd.DataFrame()),以将Polars的DataFrame转换为Pandas的DataFrame。这是Pandas 1.5.0及以后版本引入的一个功能,允许Pandas和Polars之间的更直接和高效的转换。

df_pandas = (
    pd.DataFrame(df)
    .head()
)

df_pandas

  0  1       2     3  4  5   ...     9      10    11           12   13     14
0  0  3    male  22.0  1  0  ...    man   True  None  Southampton   no  False
1  1  1  female  38.0  1  0  ...  woman  False     C    Cherbourg  yes  False
2  1  3  female  26.0  0  0  ...  woman  False  None  Southampton  yes   True
3  1  1  female  35.0  1  0  ...  woman  False     C  Southampton  yes  False
4  0  3    male  35.0  0  0  ...    man   True  None  Southampton   no   True

[5 rows x 15 columns]

从Pandas转换到Polars

您可以通过在Pandas的DataFrame上调用pl.DataFrame来将其转换为Polars的DataFrame。

这个调用会创建一个Polars的DataFrame对象,其内容和结构与原始的Pandas DataFrame相同,但使用了Polars的内部数据结构和优化,以提供更好的性能和内存效率。

(
    pl.DataFrame(
        df.to_pandas()
    )
    .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  │
└──────────┴────────┴────────┴──────┴───┴──────┴─────────────┴───────┴───────┘

或者通过在Pandas的DataFrame上调用pl.from_pandas

即除了直接在Pandas的DataFrame上调用pl.DataFrame来将其转换为Polars的DataFrame之外,还可以选择调用from_pandas函数来实现相同的转换。pl.from_pandas(pandas_df)会接受一个Pandas的DataFrame作为输入,并返回一个新的Polars的DataFrame,其内容与原始Pandas DataFrame相同。这两种方法都是将Pandas数据转换为Polars格式的有效方式。

(
    pl.from_pandas(
        df.to_pandas()
    ).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  │
└──────────┴────────┴────────┴──────┴───┴──────┴─────────────┴───────┴───────┘

两种方法都是等价的。

将Series转换为Pandas

您可以使用to_pandas方法将Series转换为Pandas的Series,这个操作会克隆数据。

在这里,Series 指的是 Polars 中的序列对象(类似于 Pandas 中的 Series)。to_pandas可以将Polars 的 Series 转换为 Pandas 的 Series。由于数据是在两个库之间转换的,因此原始数据不会被修改,而是被克隆(即复制)到新的 Pandas Series 中。这是确保数据一致性和避免潜在副作用的常见做法。

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

0    22.0
1    38.0
2    26.0
3    35.0
4    35.0
Name: age, dtype: float64

或者,您可以在Pandas中使用PyArrow扩展类型进行零拷贝转换

也就是说,除了上述的转换方法外,还可以在Pandas和Polars之间进行数据转换,且这种转换方式可以实现零拷贝(zero-copy)。具体来说,您可以在Pandas中使用PyArrow扩展类型来与Polars进行数据交换。PyArrow是一个跨语言的库,用于高效地读写各种格式的数据,包括表格型数据。通过利用PyArrow的特性和优化,可以实现数据在Pandas和Polars之间的直接传输,而无需进行数据的复制,从而提高了转换的效率。不过,需要注意的是,这种零拷贝转换可能需要特定的条件和设置才能实现。

(
    df['age']
    .to_pandas(use_pyarrow_extension_array=True)
    .head()
)

0    22.0
1    38.0
2    26.0
3    35.0
4    35.0
Name: age, dtype: double[pyarrow]

Polars简明基础教程系列

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

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

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

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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值