当前位置: 首页 > 知识库问答 >
问题:

Spark:保存按“虚拟”列分区的DataFrame

秦奇
2023-03-14

我使用PySpark完成经典的ETL工作(加载数据集、处理数据集、保存数据集),并希望将我的数据帧保存为由“虚拟”列分区的文件/目录;我所说的“虚拟”是指我有一个列时间戳,它是一个包含ISO 8601编码日期的字符串,我想按年/月/日进行分区;但是我实际上在DataFrame中既没有年、月也没有日列;我有这个时间戳,可以从中派生出这些列,但是我不希望我的resultat项序列化这些列中的一个。

将数据帧保存到磁盘生成的文件结构应如下所示:

/ 
    year=2016/
        month=01/
            day=01/
                part-****.gz

有没有办法用Spark/Pyspark做我想做的事?

共有1个答案

翟鹏
2023-03-14

用于分区的列不包括在序列化数据本身中。例如,如果创建如下数据帧

df = sc.parallelize([
    (1, "foo", 2.0, "2016-02-16"),
    (2, "bar", 3.0, "2016-02-16")
]).toDF(["id", "x", "y", "date"])

并将其写为:

import tempfile
from pyspark.sql.functions import col, dayofmonth, month, year
outdir = tempfile.mktemp()

dt = col("date").cast("date")
fname = [(year, "year"), (month, "month"), (dayofmonth, "day")]
exprs = [col("*")] + [f(dt).alias(name) for f, name in fname]

(df
    .select(*exprs)
    .write
    .partitionBy(*(name for _, name in fname))
    .format("json")
    .save(outdir))

单个文件不包含分区列:

import os

(sqlContext.read
    .json(os.path.join(outdir, "year=2016/month=2/day=16/"))
    .printSchema())

## root
##  |-- date: string (nullable = true)
##  |-- id: long (nullable = true)
##  |-- x: string (nullable = true)
##  |-- y: double (nullable = true)

分区数据仅存储在目录结构中,不会在序列化文件中复制。仅当您读取的完整或部分目录树:

sqlContext.read.json(outdir).printSchema()

## root
##  |-- date: string (nullable = true)
##  |-- id: long (nullable = true)
##  |-- x: string (nullable = true)
##  |-- y: double (nullable = true)
##  |-- year: integer (nullable = true)
##  |-- month: integer (nullable = true)
##  |-- day: integer (nullable = true)

sqlContext.read.json(os.path.join(outdir, "year=2016/month=2/")).printSchema()

## root
##  |-- date: string (nullable = true)
##  |-- id: long (nullable = true)
##  |-- x: string (nullable = true)
##  |-- y: double (nullable = true)
##  |-- day: integer (nullable = true)
 类似资料:
  • 根据Spark 1.6.3的文档,应该保留结果数据表中的分区数: 返回由给定分区表达式分区的新DataFrame,保留现有的分区数 Edit:这个问题并不涉及在Apache Spark中删除空DataFrame分区的问题(例如,如何在不产生空分区的情况下沿列重新分区),而是为什么文档所说的内容与我在示例中观察到的内容不同

  • 本文向大家介绍虚拟内存和缓存内存之间的区别,包括了虚拟内存和缓存内存之间的区别的使用技巧和注意事项,需要的朋友参考一下 在计算机环境中,内存是至关重要的部分,因为它是唯一负责系统性能和系统存储容量的部分。众所周知,内存负责任何应用程序的加载和执行,还用于存储其数据,以后可被其使用,因此在加载或安装应用程序之前了解系统的内存配置非常重要。 现在,在本主题中基本上将要讨论的是两种类型的存储器,即虚拟存

  • 主要内容:虚拟内存如何工作?,按需分页,虚拟内存管理系统的快照虚拟内存是一种存储方案,为用户提供了一个拥有非常大的主内存的幻觉。 这是通过将辅助存储器的一部分作为主存储器来完成的。 在这种方案中,用户可以加载比可用主存更大的进程,因为存在内存可用于加载进程的错觉。 操作系统不是在主内存中加载一个大进程,而是在主内存中加载多个进程的不同部分。 通过这样做,多程序的程度将会增加,因此CPU利用率也会增加。 虚拟内存如何工作? 在现代语言中,虚拟内存近来变得非常普

  • 虚拟列表可以用来渲染有大量数据的列表,并且不有有任何的性能问题。并且,它和所有的Framework7组件都是兼容的,包括搜索栏、无限滚动、下拉刷新、滑动删除和可排序列表。 虚拟列表的HTML结构 虚拟列表打HTML结构非常简单,他和常见的 列表 或者 多媒体列表只有一个区别,你必须把它的内容设置为空的。 <!-- Virtual List --> <div class="list-block vi

  • 正如我在Spark Dataframe中所知,对于多个列,可以使用以下Dataframe snapshot中所示的相同名称: 上面的结果是通过将数据帧连接到自身创建的,您可以看到有列,其中包含两个和。 问题是,当我尝试使用列进行更多计算时,我找不到选择的方法,我尝试了和,两者都在下面返回了我的错误消息: 无论如何,在Spark API中,我可以再次区分列和重复的名称吗?或者可以通过某种方式让我更改

  • 本文向大家介绍虚拟化和云计算的区别分析,包括了虚拟化和云计算的区别分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了虚拟化和云计算的区别。分享给大家供大家参考,具体如下: 经常有人讨论这两者的区别,在这个行业时间长,听到的也自然很多,这里做一个总结。下面的观点,我想没有对和错,只是理解不同。 所谓虚拟化,虚拟机,vps,其实是差不多一个意思 所谓云计算,广义上肯定是包括一切,不过狭义一点