我一直在尝试使用 #Id 过滤掉标题行,并将id number
作为列添加到正在处理的 file_name 。以下是要处理的示例文件
文件1:
#sample first line
#Id: abcdef
col1,col2,col3
1,2,3
2,3,3
4,5,6
文件2:
#sample first line
#Id: ghjklo
col1,col2,col3
5,1,3
2,5,8
8,0,4
当我尝试构建数据框并打印结果时,我可以使用下面的代码段将文件名添加为列。
par_df = spark.read.schema(schema) \
.option("header", "true") \
.format("com.databricks.spark.csv") \
.option("mode", "DROPMALFORMED")\
.csv("s3a://" + bucket "/"+prefix+"/").withColumn("FileName", func.input_file_name())
这会过滤掉标题信息,下面是打印结果的代码段。
parsed_diff_df = par_df.select(
par_df['col1'],
par_df['col2'])
parsed_diff_df.registerTempTable("parsed_diff_df_table")
results = sqlContext.sql("select col1, col2, FileName from "
"parsed_diff_df_table").collect()
这是我得到的结果,无法附加Id列,因为它已经过滤掉了。
1,2,3,File1
2,3,3,File1
4,5,6,File1
5,1,3,File2
2,5,8,File2
8,0,4,File2
预期结果如下。
1,2,3,abcdef,File1
2,3,3,abcdef,File1
4,5,6,abcdef,File1
5,1,3,ghjklo,File2
2,5,8,ghjklo,File2
8,0,4,ghjklo,File2
我也试过这个,但没有运气。
rdd = sc.textFile("s3a://" + bucket + "/"+prefix+"/").flatMap(lambda line: line.split("\n")).filter(lambda line: '#' in line)
results = rdd.collect()
for row in results:
print row
答案 0 :(得分:2)
您可以将每个文件的FileName
映射到id
:
让我们编写一个函数来提取id值:
import re
def extract_id(l):
return re.search('#Id: ([a-z]+)\\n', line).group(1)
让我们将文件读作RDD:
file_id = sc.wholeTextFiles("/user/at967214/test.csv").filter(lambda l: l[1][0]=='#').map(lambda l: [l[0], extract_id(l[1])])
现在是数据框:
file_id_df = spark.createDataFrame(file_id, ["FileName", "id"])
现在您可以将其加入第一个数据框
par_df.join(file_id_df, "FileName", "inner")
答案 1 :(得分:1)
不使用csv loader,而是实现以下步骤来实现:
我是java开发人员,对Python没有多少帮助,类似的东西可能对你有帮助:
pairRdd=sc.wholeTextFiles('<path>')
#it exactly wont work, make required changes:
def appendId( record ):
splits = record.splitlines()
id=splits[0].split(':')[1].strip()
print(id)
output=[]
for s in xrange(2,len(splits)):
output.append(splits[s]+','+id)
return output
objRDD=pairRdd.flatMapValues(appendId)
.map(lambda key,val:val.split(','))
.map(lambda p:Row(col1=int(p[0]), col2=int(p[1])........FileName=p[3]))
dataframe=spark.createDataFrame(objRdd)
.....
等效Java:
JavaPairRDD<String[]> inputRdd = sparkContext.wholeTextFiles("<xyz path>");;
inputRdd.flatMapValues(new Function<String, Iterable<String>>() {
@Override
public Iterable<String> call(String v1) throws Exception {
String[] splits = v1.split( System.getProperty("line.separator"));
String id = splits[0].split(":")[1].trim();
List<String> values = new ArrayList<String>();
for (int i =2;i<splits.length;i++){
values.add(String.format("%s,%s", splits[i],id));
}
return values;
}
}
).map(s->s._2().split(","));