与纯python替代

时间:2017-06-18 17:04:50

标签: python apache-spark pyspark apache-spark-mllib

我转换了下面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'。

3 个答案:

答案 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()函数的驱动程序计算机,可以破坏第一个函数的功能。所以你实际上做的是在只有一台机器的驱动程序机器上运行程序。因此没有加速。