我有一个要求在哪里我需要在spark / scala中读取excel文件(扩展名为.xlsx)。我需要创建一个数据框,其中包含从excel读取的数据,并在其上面应用/编写sql查询以进行一些分析。 excel文件有一些列标题/标题,如" time_spend_company(年)"," average_monthly_hours(小时)"等作为标题本身的空格,这些空格导致我在加载的数据帧上应用任何sql查询时出现问题。
我正在使用 com.crealytics.spark.excel 库来解析excel内容,我的代码如下所示
val empFile = "C:\\EmpDatasets.xlsx"
val employeesDF = sc.sqlContext.read
.format("com.crealytics.spark.excel")
.option("sheetName", "Sheet1")
.option("useHeader", "true")
.option("treatEmptyValuesAsNulls", "false")
.option("inferSchema", "false")
.option("location", empFile)
.option("addColorColumns", "False")
.load()
employeesDF.createOrReplaceTempView("EMP")
我想在这些列上应用分组和其他聚合函数,我正面临着如下列这些列的问题,我的要求是在time_spent_company列上应用group by并获取它
val expLevel = sc.sqlContext.sql("Select 'time_spend_company (Years)' as 'Years_spent_in_company',count(1) from EMP where left_company = 1 group by 'time_spend_company (Years)'")
expLevel.show
我需要帮助: -
注意:我只需要将其作为excel文件阅读,我无法将其转换为csv或任何其他文件格式。
答案 0 :(得分:1)
EmpDatasets.xlsx
重命名为EmpDatasets.csv
即可将其转换为CSV。使用this执行此操作。将文件设为CSV后,您可以将其读作spark.read.csv(pathToCSV)
并提供许多选项,例如:读取/跳过标题或将数据集的架构提供为spark.read.schema(schema).csv(pathToCSV)
。
此处schema
可以按照here所述创建,也可以使用spark sql Encoders Encoders.product[case_class_name].schema
val employeesDFColumns = employeesDF.columns.map(x
=> col(x.replaceAll(" ", "")))
并在数据框上应用这些新列名称。
val employeeDF = employeeDF.select(employeesDFColumns:_*)
答案 1 :(得分:1)
问题2的答案:尽管使用'
,您需要在列名开头和结尾之前使用空格。尝试以下查询它将起作用:
val expLevel = sc.sqlContext.sql("Select `time_spend_company (Years)` as `Years_spent_in_company`,count(1) from EMP where left_company = 1 group by `time_spend_company (Years)`")
问题1:使用“com.crealytics.spark.excel”加载excel是可以的。我也在使用它。也可以有不同的选择。要分配不同的列名,可以使用“结构类型”定义模式,并在将数据加载到数据框期间强制使用它。 e.g
val newSchema = StructType(
List(StructField("a", IntegerType, nullable = true),
StructField("b", IntegerType, nullable = true),
StructField("c", IntegerType, nullable = true),
StructField("d", IntegerType, nullable = true))
)
val employeesDF = spark.read.schema(newSchema)
.format("com.crealytics.spark.excel")
.option("sheetName", "Sheet1")
.option("useHeader", "true")
.option("treatEmptyValuesAsNulls", "false")
.option("inferSchema", "false")
.option("location", empFile)
.option("addColorColumns", "False")
.load()
现在将通过a,b,c和d访问前四个列名称。运行以下查询,它将适用于新的列名。
sc.sqlContext.sql("select a,b,c,d from EMP").show()
答案 2 :(得分:0)
对于版本0.13.5
,您需要一组不同的参数:
def readExcel(file: String): DataFrame = {
sqlContext.read
.format("com.crealytics.spark.excel")
.option("dataAddress", "'sheet_name'!A1") // Optional, default: "A1"
.option("header", "true") // Required
.option("treatEmptyValuesAsNulls", "false") // Optional, default: true
.option("inferSchema", "true") // Optional, default: false
.option("addColorColumns", "false") // Optional, default: false
.option("timestampFormat", "MM-dd-yyyy HH:mm:ss") // Optional, default: yyyy-mm-dd hh:mm:ss[.fffffffff]
.option("maxRowsInMemory", 20) // Optional, d[#All]efault None. If set, uses a streaming reader which can help with big files
.load(file)
}
maven依赖项:
<dependency>
<groupId>com.crealytics</groupId>
<artifactId>spark-excel_2.11</artifactId>
<version>0.13.5</version>
</dependency>