Spark DataFrame与Koalas DataFrame的区别及Koalas内部运行机制疑问
Koalas内部运行机制核心概念答疑
三个核心层的本质
我们先明确三个概念的真实定位:
- Spark DataFrame:Spark原生的分布式数据集,所有计算最终都落到这一层执行,是实际存储分布式数据、触发作业的实体。
- Internal Frame:Koalas实现pandas兼容的核心中间层,本质是元数据容器,存储内容包括:Spark列名到用户可见的Koalas列名的映射、索引元信息(pandas风格的行索引结构、是否为多层索引等)、Schema映射规则、数据排序规则这些pandas有但Spark原生没有的元数据。它不存储实际数据,只存储「怎么把Spark DataFrame转换成用户感知的pandas风格DataFrame」的规则。
- Koalas DataFrame(简称KDF):不是纯逻辑概念,是用户直接操作的Python对象实例,内部持有两个核心属性:一个是对应的Internal Frame实例,一个是底层绑定的Spark DataFrame实例。可以把它理解为套了pandas接口壳的封装对象,所有你调用的pandas风格API,本质都是调用这个对象的方法,由它内部修改持有的Internal Frame或者Spark DataFrame来实现业务逻辑。
常见困惑解答
创建/不创建新的Koalas DataFrame是什么意思?
简单说就是是否生成新的KDF对象实例:
- 默认情况下你调用
kdf.dropna()这类不带inplace=True的方法时,Koalas会复制原KDF的基础属性,修改其中的Internal Frame(或者同时生成新的Spark DataFrame)之后,返回一个新的KDF实例,原KDF对象完全不变,这就是「创建新的Koalas DataFrame」。 - 加了
inplace=True时,不会生成新的KDF对象,而是直接修改当前KDF实例内部持有的Internal Frame、以及绑定的Spark DataFrame引用,原KDF对象的ID不变,但它对应的实际数据和元数据已经变更,这就是「不创建新的Koalas DataFrame」。
为什么API调用不一定生成新的Spark DataFrame?
很多pandas风格的操作本质只是元数据修改,不需要改动实际的Spark数据。比如你给KDF改列名kdf.columns = ['a','b','c'],这个操作只需要修改Internal Frame里的列名映射规则,底层的Spark DataFrame的列名完全不用改,也不需要生成新的Spark DataFrame,用户看到的列名就已经更新了,这种情况就只会生成新的Internal Frame,不会触碰底层Spark DataFrame。
只有涉及到实际数据修改的操作,比如过滤空值、新增计算列、聚合等,才需要生成新的Spark DataFrame实例。
执行kdf.dropna(..., inplace=True)的具体过程是什么?
你提到的「保持Koalas DataFrame不变,修改Internal Frame和Spark DataFrame」的逻辑是这样的:
dropna属于需要实际过滤数据的操作,所以Koalas会先基于当前绑定的Spark DataFrame,生成过滤掉空值后的新Spark DataFrame实例。- 然后根据操作逻辑更新Internal Frame的元数据:比如过滤后行数变化,需要更新索引映射规则,如果有索引列需要同步调整索引元信息。
- 因为加了
inplace=True,所以不会返回新的KDF对象,而是直接把当前KDF实例内部持有的Spark DataFrame引用替换成新生成的实例,同时把Internal Frame替换成更新后的实例。从用户视角看你操作的还是原来那个KDF变量,但它内部绑定的元数据和底层数据已经完成了更新。
内容的提问来源于stack exchange,提问作者figs_and_nuts
相关产品推荐
相关产品推荐

