期末大作业
。
hive 内部表和外部表的差异总结如下:
对比内容 | 内部表 | 外部表 |
---|---|---|
数据存储位置 | 内部表数据存储的位置由 hive-site.xml 中的hive.Metastore.warehouse.dir 参数指定,默认情况下,表的数据存储在 HDFS 的/user/hive/warehouse/数据库名.db/表名/ 目录下 |
外部表数据的存储位置创建表时由Location 参数指定 |
导入数据 | 在导入数据到内部表,内部表将数据移动到自己的数据仓库目录下, 数据的生命周期由 Hive 来进行管理 |
外部表不会将数据移动到自己的数据仓库目录下, 只是在元数据中存储了数据的位置 |
删除表 | 删除元数据(metadata)和 HDFS 数据文件 | 只删除元数据(metadata) |
安全性 | 低(容易误删数据) | 高 |
hive 分桶是基于 hive 表指定列进行 hash,根据不同的 hash 值进行分组,将数据文件分割为若干小文件。
优点是优化 join 查询和抽样查询,缺点是会生成很多小文件。
hbase 是数据存储引擎,hive 是数据分析引擎。
hbase 适用于海量数据高吞吐、低时延的存储和读取。
hive 适用于利用易用性好的 SQL 对存储于 hdfs 上半结构化或者非结构化的海量数据进行查询与分析。
Spark中计算阶段划分的依据是Shuffle,而不是操作函数的类型,并不是所有的函数都有Shuffle
过程。
Spark把不需要Shuffle的依赖,称为窄依赖。需要Shuffle的依赖,称为宽依赖。
hadoop 是大数据框架,侧重于数据存储,也支持计算,通过 mapreduce 将计算过程划分为 map 和 reduce 两个阶段。
Spark 是大数据计算框架,侧重于计算,它没有分布式文件系统,必须依赖于其他数据源系统。和 mapreduce 类似,spark 也是将计算过程拆分为 map 、reduce 两个阶段。
hadoop 生态是现如今大数据处理的基石。了解和掌握 hadoop 生态组件是学习大数据处理的必经之路。hadoop 生态相关的组件一直在高速发展,拥抱变化。我们要跟紧 hadoop 生态发展的步伐,努力学习最实用、最先进的大数据处理技术和组件。
从新闻文章中发现热门话题和趋势话题是舆论监督的一项重要任务。在这个项目中,你的任务是使用新闻数据集进行文本数据分析,使用 Python 中 pySpark 的 DataFrame 和 RDD 的 API。问题是计算新闻文章数据集中每年各词的权重,然后选择每年 top-k个最重要的词。
您将使用的数据集包含多年来发布的新闻标题数据。在这个文本文件中,每一行都是一篇新闻文章的标题,格式为“ date,term1 term2… …”。日期和文本用逗号分隔,文本用空格字符分隔。示例文件如下:
20030219,council chief executive fails to secure position
20030219,council welcomes ambulance levy decision
20030219,council welcomes insurance breakthrough
20030219,fed opp to re introduce national insurance
20040501,cowboys survive eels comeback
20040501,cowboys withstand eels fightback
20040502,castro vows cuban socialism to survive bush
20200401,coronanomics things learnt about how coronavirus economy
20200401,coronavirus at home test kits selling in the chinese community
20200401,coronavirus campbell remess streams bear making classes
20201015,coronavirus pacific economy foriegn aid china
20201016,china builds pig apartment blocks to guard against swine flu
您需要忽略诸如“ to”、“ the”和“ in”之类的停用词。该文件存储了停用词。
为了计算一个文本的为期一年的权重,请使用 TF/IDF 模型。具体而言,TF 和 IDF 可计算为:
T F ( 文本 t , 年份 y ) = 在 y 年份中,包含文本 t 的新闻标题数量 TF(文本 t, 年份 y) = 在 y 年份中,包含文本 t 的新闻标题数量 TF(文本t,年份y)=在y年份中,包含文本t的新闻标题数量
I D F ( 文本 t , 数据集 D ) = l o g 10 ( 在数据集 D 中年份的总数 / 含有文本 t 的年份总数 ) IDF(文本 t,数据集 D) = log10(在数据集D中年份的总数/含有文本t的年份总数) IDF(文本t,数据集D)=log10(在数据集D中年份的总数/含有文本t的年份总数)
最后,文本 t 对于年份 y 的权重计算如下:
W e i g h t ( 文本 t , 年份 y , 数据集 D ) = T F ( 文本 t , 年份 y ) ∗ I D F ( 文本 t , 数据集 D ) Weight(文本 t, 年份 y, 数据集 D) = TF(文本 t, 年份 y)* IDF(文本 t, 数据集 D) Weight(文本t,年份y,数据集D)=TF(文本t,年份y)∗IDF(文本t,数据集D)
请使用 import math
并使用 math.log10()
计算文本权重,并将结果四舍五入到小数点后6位。
如果数据集中有 N 年,那么您应该在最终输出文件中输出正好 N 行,并且这些行按年份升序排序。在每一行中,您需要以
的格式输出 k 对list,并且这些对按照文本权重降序排序。如果两个文本具有相同的权重,则按字母顺序对它们进行排序。具体来说,每行的格式类似于:
“year**\t** Term1,Weight1;Term 2,Weight2;… …;Termk,Weightk” 。例如,给定上述数据集和 k = 3,输出应该是:
2003 council,1.431364;insurance,0.954243;welcomes,0.954243
2004 cowboys,0.954243;eels,0.954243;survive,0.954243
2020 coronavirus,1.908485;china,0.954243;economy,0.954243
Dataframe:
spark-submit project_df.py file:///testcase_top20/sample.txt file:///res_df file:///stopwords.txt k
RDD:
spark-submit project_rdd.py file:///testcase_top20/sample.txt file:///res_rdd file:///stopwords.txt k
其中 file://
后跟随本地文件目录地址。
Dataframe:
from pyspark.sql.session import SparkSession
from pyspark.sql.functions import *
import sys
def takeTopK(pairList, k):
#填入获得前k个排名的函数
pairList.show(k)
class Project2:
def run(self, inputpath, outputpath, stopwords, k):
spark = SparkSession.builder.master("local").appName("project2_df").getOrCreate()
#填入以下两个函数的参数
fileDF = spark.read.text(inputpath)
swlist = spark.sparkContext.broadcast(stopwords)
headlineDF = fileDF.select(split(fileDF['value'], ',').getItem(0).substr(0, 4).alias('year'),
split(fileDF['value'], ',').getItem(1).alias('headline'))
headlineDF = headlineDF.withColumn('word', split('headline', ' '))
headlineDF2 = headlineDF.select('year', array_distinct(headlineDF.word).alias('word'))
headlineDF3 = headlineDF2.withColumn('word', explode('word'))
yearwordsDF = headlineDF3[~headlineDF3.word.isin(swlist.value)]
#写出TF计算的函数
TF =
totalYear = yearwordsDF.select('year').distinct().count()
#写出DF计算的函数
DF =
TFIDF = TF.join(DF, TF.word == DF.word).select(TF.year, TF.word, TF.TF, DF.DF)
weightDF = TFIDF.withColumn('weight', round(TFIDF.TF * log10(totalYear / TFIDF.DF), 6)).select('year', 'word',
'weight')
groupDF = weightDF.groupBy('year').agg(collect_list(struct('word', 'weight')).alias('pair'))
topkUDF = udf(lambda z, k: takeTopK(z, k))
res = groupDF.withColumn('pair', topkUDF('pair', lit(int(k)))).orderBy('year')
res2 = res.coalesce(1).orderBy('year').withColumn('result', concat_ws('\t', 'year', 'pair')).select('result')
res2.write.text(outputPath)
spark.stop()
if __name__ == "__main__":
if len(sys.argv) != 5:
print("Wrong arguments")
sys.exit(-1)
Project2().run(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
RDD:
from pyspark import SparkContext, SparkConf
from operator import add
from math import log10
import heapq
import sys
def takeTopK(pairList, k):
#填入获得前k个排名的函数
pairList.show(k)
class Project2:
def run(self, inputpath, outputpath, stopwords, k):
conf = SparkConf().setAppName("project2_rdd")
sc = SparkContext(conf=conf)
# 填入以下两个函数的参数
filerdd = sc.textFile(inputpath)
swlist = sc.broadcast(stopwords)
#写出以下标题、年度词、TF、总年计算的函数
headlines =
yearwords =
TF =
totalYear =
# DF = yearwords.map(lambda x:(x[0][1], x[0][0])).countByKey()
DF = yearwords.map(lambda x: (x[0][1], x[0][0])).groupByKey().map(lambda x: (x[0], len(x[1])))
TFIDF = TF.join(DF).map(lambda x: (x[1][0][0], (round(x[1][0][1] * log10(totalYear / x[1][1]), 6), x[0])))
res = TFIDF.groupByKey().map(lambda x: (x[0], list(x[1]))).mapValues(lambda x: takeTopK(x, int(k)))
res2 = res.coalesce(1).sortByKey().map(
lambda x: f'{x[0]}\t{";".join([item[1] + "," + str(item[0]) for item in x[1]])}')
res2.saveAsTextFile(outputPath)
sc.stop()
if __name__ == "__main__":
if len(sys.argv) != 5:
print("Wrong arguments")
sys.exit(-1)
Project2().run(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])