数据帧交换协议
数据帧互换协议(Dataframe Interchange Protocol),是为了提高不同数据帧库之间的互操作性而设计的。
想象一下,你有很多不同类型的储物箱(在这里比喻为不同的数据帧库,如 Pandas、Polars、Dask 等),每种储物箱都有自己的独特之处,比如有的储物箱容量大、有的开合速度快、有的防水防尘。但是,当你需要从储物箱里拿东西去给朋友看(在这里比喻为可视化库,如 Seaborn、Plotly 和 Altair)时,你会发现每个储物箱的开锁方式都不一样,这就给“拿东西”造成了不便。
数据帧互换协议就像是一个通用的钥匙,它允许不同的储物箱(数据帧库)和朋友(可视化库)之间建立一种标准的沟通方式。也就是说,不管储物箱(数据帧库)内部结构如何,只要它们都支持数据帧互换协议,那么你的朋友(可视化库)就能知道如何从这些储物箱中取出东西(数据),而不需要了解每个储物箱的具体细节。
Seaborn, Plotly 和 Altair 这些可视化库现在能够通过数据帧互换协议来直接与 Polars 这个数据帧库进行交互。这意味着,当你的朋友(可视化库)想要看你的东西(数据)时,只需要按照通用钥匙(数据帧互换协议)的方式来操作,而不用关心你是用的哪种储物箱(数据帧库)。这样,就大大提高了效率和灵活性,你不再需要为了配合朋友的要求而把东西从一个储物箱倒腾到另一个储物箱里。
简而言之,数据帧互换协议就像是一座桥梁,连接了数据帧库和可视化库,使得数据的可视化过程更加顺畅和高效,而无需为每一个库的特定细节操心。
下面的Seaborn、Plotly 和 Altair 通过数据帧交换协议支持 Polars。该协议是一种方式,允许第三方包(例如可视化库)与不同的数据帧库一起工作,而无需显式支持这些库。
实际上,使用交换协议意味着我们可以将Polars的DataFrame直接用于Plotly的许多图表中。然而,由于Plotly没有原生支持Polars,因此无法保证所有图表都能与Polars的DataFrame一起工作。在某些情况下,您可能需要转换为Pandas。
如果您对交换协议的工作原理感到好奇,以下是一个简化版本:
- Plotly 检查传递给它的数据对象的类型,并发现它不是 Pandas 的 DataFrame
- Plotly 然后检查传递给它的对象是否具有__dataframe__命名空间
- 如果 Plotly 发现对象具有__dataframe__命名空间,它将使用该命名空间中的通用命令来执行所需的操作(例如,从 DataFrame 中提取命名列,检查列的 dtype 并遍历列)
您可以在此处查看Polars DataFrame上__dataframe__命名空间中的方法:
[el for el in dir(df.__dataframe__()) if not el.startswith("__")]
这些方法是我们在本课程中学习的标准Polars方法的封装。数据帧交换协议本身是一个快速发展的项目,因此其功能会不断增加。
Altair
我们可以直接将DataFrame传递给Altair
alt.Chart(
passenger_class_counts_df,
width=600
).mark_bar().encode(
x="pclass:N",
y="count:Q",
color="pclass:N",
)
与Plotly一样,Altair也通过数据帧交换协议支持Polars。与Plotly相同,也存在相同的注意事项。
另外,在pycharm中用Altair绘制的图像视乎显示不了,用jupyter notebook就很轻松地显示出来。
练习
在练习中,您将加深对以下内容的理解:
- 从Polars创建图表
练习1
我们首先创建一个自行车销售的DataFrame,并将字符串列名中的空格替换为_(有关pipe的更多信息,请参阅选择和转换数据部分中的转换DataFrame讲座)
import polars as pl
df = pl.DataFrame(
{'customer age':[31,45,18,26,22,17,20,19,21,33,32,42,35,17,15,18,19,20,22,18,19,21],
'len':[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
}
)
df_bike =df.pipe(
lambda df: df.rename({col:col.replace(" ","_") for col in df.columns})
)
df_bike.head(2)
shape: (2, 2)
┌──────────────┬─────┐
│ customer_age ┆ len │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞══════════════╪═════╡
│ 31 ┆ 1 │
│ 45 ┆ 1 │
└──────────────┴─────┘
我们首先需要执行group_by来获取数据
customer_count_df = (
df_bike
.group_by("customer_age")
.len()
.sort("customer_age")
)
使用内置的绘图方法和您首选的可视化库,制作一个customer_age列的条形图,显示按客户年龄分类的自行车销售量
<blank>
解决方案
hvPlot
(
customer_count_df
.plot
.bar(
x="customer_age",
y="len",
width=1000
)
)
Matplotlib
plt.bar(
x=customer_count_df["customer_age"],
height=customer_count_df["len"],
)
Seaborn
sns.barplot(
customer_count_df.to_pandas(use_pyarrow_extension_array=True),
x="customer_age",
y="len"
)
Plotly
px.bar(
customer_count_df.with_columns(pl.col("customer_age").cast(pl.Utf8)),
x="customer_age",
y="len",
)
Altair
(
alt.Chart(
customer_count_df,
width=600
)
.mark_bar()
.encode(
x="customer_age:N",
y="len:Q"
)
)
Polars简明基础教程系列
Polars简明基础教程十四:可视化(四)
Polars简明基础教程十三:可视化(三)
Polars简明基础教程十二:可视化(二)
Polars简明基础教程十一:可视化(一)
Polars简明基础教程十:Numpy和Pandas的相互转换(2)
Polars简明基础教程九:Numpy和Pandas的相互转换(1)
Polars简明基础教程八:Series 和 DataFrame 以及它们之间的转换_B
Polars简明基础教程七:Series 和 DataFrame 以及它们之间的转换_A
Polars简明基础教程六:什么是Polars的“DataFrame(数据框)_下”
Polars简明基础教程五:什么是Polars的“DataFrame(数据框)_上”
Polars简明基础教程四:懒惰模式 2:评估查询
Polars简明基础教程三:懒惰模式 1:引入懒惰模式(续)
Polars简明基础教程二:懒惰模式 1:引入懒惰模式
Polars简明基础教程一:Polars快速入门