我转换了下面python粘贴的现有代码在pyspark中。
Python代码:
import json
import csv
def main():
# create a simple JSON array
with open('paytm_tweets_data_1495614657.json') as str:
tweetsList = []
# change the JSON string into a JSON object
jsonObject = json.load(str)
#print(jsonObject)
# # print the keys and values
for i in range(len(jsonObject)):
tweetsList.insert(i,jsonObject[i]["text"])
#print(tweetsList)
displaySentiment(tweetsList)
def displaySentiment(tweetsList):
aDict = {}
from sentiment import sentiment_score
for i in range(len(tweetsList)):
aDict[tweetsList[i]] = sentiment_score(tweetsList[i])
print (aDict)
with open('PaytmtweetSentiment.csv', 'w') as csv_file:
writer = csv.DictWriter(csv_file, fieldnames = ["Tweets", "Sentiment Value"])
writer.writeheader()
writer = csv.writer(csv_file)
for key, value in aDict.items():
writer.writerow([key, value])
if __name__ == '__main__':
main()
转换后的Pyspark代码:
import json
import csv
import os
from pyspark import SparkContext, SparkConf
from pyspark.python.pyspark.shell import spark
os.environ['PYSPARK_PYTHON'] = "/usr/local/bin/python3"
def main():
path = "/Users/i322865/DeepInsights/bitbucket-code/ai-engine/twitter-sentiment-analysis/flipkart_tweets_data_1495601666.json"
peopleDF = spark.read.json(path).rdd
df = peopleDF.map(lambda row: row['text'])
displaySentiment(df.collect())
def displaySentiment(tweetsList):
from sentiment import sentiment_score
aDict = sentiment_score(tweetsList)
#
with open('paytmtweetSentiment.csv', 'w') as csv_file:
writer = csv.DictWriter(csv_file, fieldnames = ["Tweets", "Sentiment Value"])
writer.writeheader()
writer = csv.writer(csv_file)
for i in range(len(tweetsList)):
writer.writerow([tweetsList[i], aDict[i]])
print([tweetsList[i], aDict[i]])
if __name__ == '__main__':
conf = SparkConf().setAppName("Test").setMaster("local")
sc = SparkContext.getOrCreate(conf=conf)
main()
我运行了这两个程序,但没有看到任何显着的性能提升。我错过了什么?请问你能想出一些想法吗?
另外,我应该使用'减少'还有?我目前只使用' map'。
答案 0 :(得分:2)
如果你想在PySpark中并行处理某些内容,请不要collect()
回到Python列表
def calc_sentiment(tweetsDf): # You should pass a dataframe
from sentiment import sentiment_score
# Add a new column over the Tweets for the sentiment
return tweetsDf.withColumn('sentiment_score', sentiment_score(tweetsDf.text))
显然,sentiment_score
也需要更改为接受并返回PySpark Column
然后,你会有这样的东西
def main():
path = "..../twitter-sentiment-analysis/flipkart_tweets_data_1495601666.json"
twitterDf = spark.read.json(path)
# Don't call collect, only sample the Dataframe
sentimentDf = calc_sentiment(twitterDf)
sentimentDf.show(5)
# TODO: Write sentimentDf to a CSV
sentimentDf.write.csv(....)
答案 1 :(得分:2)
除了其他人指出的收集问题之外,你的PySpark实现可能会因为Spark不适合你当前的用例而变慢。
从根本上说,Spark旨在加速对非常大的分布式数据集(多台机器)的操作,而不是本地并行化。为实现这一目标,它使用了架构结构和流程。
对于单个/小型数据集,这种开销很容易成为主导并且会降低解决方案的速度。 This article讨论了Hadoop的使用,它非常相似。您可能尝试过multiprocessing了吗?
如果您确定Spark适合您,那么发布一个详细说明您的Spark设置,如何衡量您的表现以及您的数据集的新问题可能会有所帮助。
答案 2 :(得分:0)
我认为你没有看到任何加速是完全有道理的。您首先创建一个RDD(因此您分发数据)然后收集它们以运行您的第二个函数,即分析函数。实际上,通过将所有数据收集到继续应用displaySentiment()函数的驱动程序计算机,可以破坏第一个函数的功能。所以你实际上做的是在只有一台机器的驱动程序机器上运行程序。因此没有加速。