Pyspark从csv文件中读取delta / upsert数据集

时间:2017-06-28 17:27:46

标签: csv apache-spark pyspark spark-dataframe

我有一个定期更新的数据集,我收到的是一系列CSV文件,提供更改。我想要一个只包含每行最新版本的Dataframe。有没有办法在Spark / pyspark中加载允许并行性的整个数据集?

示例:

  • 文件1(键,值) 1,ABC 2,DEF 3,GHI
  • 文件2(键,值) 2,XYZ 4,UVW
  • 文件3(键,值) 3,JKL 4,MNO

应该导致: 1,ABC 2,XYZ 3,JKL 4,MNO

我知道我可以通过顺序加载每个文件,然后使用反连接(以取出要替换的旧值)和联合来实现这一点,但这不会让工作负载并行。

2 个答案:

答案 0 :(得分:4)

放大@pandaromeo的回答,这似乎有效......

from pyspark.sql import Window
from pyspark.sql.functions import row_number, desc, input_file_name


# load files, marking each with input file name
df = spark.read.csv(files).withColumn("_ifn", input_file_name())

# use a window function to order the rows for each ID by file name (most recent first)
w = Window.partitionBy(primaryKey).orderBy(desc('_ifn'))
df = df.withColumn("_rn", row_number().over(w))

# grab only the rows that were first (most recent) in each window
# clean up working columns
df = df.where(df._rn == 1).drop("_rn").drop("_ifn")

答案 1 :(得分:1)

你可以

from pyspark.sql.functions import * 
alls = spark.read.csv("files/*").withColumn('filename', input_file_name())

将加载目录中的所有文件,并允许您对包含文件名的列进行操作。

我假设文件名有某种时间戳或键,您可以使用window和row_number函数来区分和排序它们。