摘要:下面,讓我們進(jìn)入本次的之旅項(xiàng)目展示由于流浪地球的大熱以及筆者對(duì)此的欣賞,因此,此次的項(xiàng)目為分析中國電影票房排行。在中國電影票房排行榜的前名中,吳京主演了戰(zhàn)狼與流浪地球,且兩者沒有其他更多的相同主演。
什么是Neo4j?
??Neo4j是一個(gè)高性能的NoSQL圖形數(shù)據(jù)庫(Graph Database),它將結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)在網(wǎng)絡(luò)上而不是表中。它是一個(gè)嵌入式的、基于磁盤的、具備完全的事務(wù)特性的Java持久化引擎,但是它將結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)在網(wǎng)絡(luò)(從數(shù)學(xué)角度叫做圖)上而不是表中。Neo4j也可以被看作是一個(gè)高性能的圖引擎,該引擎具有成熟數(shù)據(jù)庫的所有特性。
??作為圖形數(shù)據(jù)庫,Neo4j最讓人驚喜的功能就是它可以直觀地展示圖,也就是節(jié)點(diǎn)與節(jié)點(diǎn)之間的關(guān)系,當(dāng)然,它還有其它的優(yōu)勢(shì),比如:
很容易表示連接的數(shù)據(jù);
檢索/遍歷/導(dǎo)航更多的連接數(shù)據(jù)是非常容易和快速的;
能輕松地表示半結(jié)構(gòu)化數(shù)據(jù);
Neo4j CQL查詢語言命令類似于SQL,可讀性好,容易學(xué)習(xí);
使用簡單而強(qiáng)大的數(shù)據(jù)模型;
不需要復(fù)雜的連接來檢索連接的/相關(guān)的數(shù)據(jù)。
??在本文中,筆者希望能夠通過一個(gè)簡單的例子來展示Neo4j的使用以及它的強(qiáng)大之處,這無疑更適合于初學(xué)者,因?yàn)楣P者也是剛?cè)腴T。
??以下,筆者并不會(huì)過多地介紹Neo4j的操作,只是希望讀者能對(duì)Neo4j的功能有直觀的感受,至于教程之類的,可以參考文章最后的參考文獻(xiàn)。
??下面,讓我們進(jìn)入本次的Neo4j之旅~
??由于《流浪地球》的大熱以及筆者對(duì)此的欣賞,因此,此次的項(xiàng)目為分析中國電影票房排行。我們的數(shù)據(jù)來自于百度百科,用爬蟲得到我們需要的數(shù)據(jù),主要是電影的相關(guān)信息,如排名,票房,上映日期等,以及電影的主演。將數(shù)據(jù)儲(chǔ)存為CSV文件,并導(dǎo)入至Neo4j,最后得到電影的簡單分析及可視化。
??整個(gè)項(xiàng)目主要是以下三步:
數(shù)據(jù)獲?。豪门老x實(shí)現(xiàn);
數(shù)據(jù)導(dǎo)入:利用Py2neo實(shí)現(xiàn);
數(shù)據(jù)展示:利用Neo4j實(shí)現(xiàn)。
其中,Py2neo為Neo4j的Python接口。
??整個(gè)項(xiàng)目的結(jié)構(gòu)如下圖:
??接下來,筆者將詳細(xì)地介紹每一步的操作及代碼,let"s go ~
數(shù)據(jù)獲取??數(shù)據(jù)的獲取始終是一個(gè)重要的問題,好在我們有爬蟲這個(gè)工具。為了能夠展示中國電影票房排行中的電影信息以及演員與電影的關(guān)系,首先的重要一步就是獲取我們需要的需要。
??我們需要兩份數(shù)據(jù)。第一份數(shù)據(jù),就是中國電影票房排行數(shù)據(jù),網(wǎng)址為:https://baike.baidu.com/item/...,頁面如下:
??我們制作爬蟲,將這個(gè)表格爬取下來,并將表格的第一行(字段名稱)作為電影的相關(guān)信息,然后儲(chǔ)存為movies.csv。整個(gè)過程的Python代碼(movie.py)如下:(因?yàn)檫@是公開數(shù)據(jù),這個(gè)爬蟲是合理的。)
# -*- coding: utf-8 -*- import requests import pandas as pd from bs4 import BeautifulSoup url = "https://baike.baidu.com/item/%E4%B8%AD%E5%9B%BD%E7%94%B5%E5%BD%B1%E7%A5%A8%E6%88%BF/4101787" # 請(qǐng)求頭部 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"} r = requests.get(url, headers=headers) soup = BeautifulSoup(r.text.encode("ISO-8859-1"),"lxml") table = soup.find("table")("tr") movies = [] for line in table[1:]: movie = {"rank": int(line("td")[0].text), "src": line("td")[1]("a")[0]["href"], "name": line("td")[1].text, "box_office": line("td")[2].text, "avg_price": int(line("td")[3].text), "avg_people": int(line("td")[4].text), "begin_date": line("td")[5].text.strip(), } # print(movie) movies.append(movie) # print(movies) df = pd.DataFrame({"rank": [movie["rank"] for movie in movies], "src": [movie["src"] for movie in movies], "name": [movie["name"] for movie in movies], "box_office": [movie["box_office"] for movie in movies], "avg_price": [movie["avg_price"] for movie in movies], "avg_people": [movie["avg_people"] for movie in movies], "begin_date": [movie["begin_date"] for movie in movies] }) # print(df.head()) df.to_csv(r"./movies.csv", index=False)
??movies.csv中的數(shù)據(jù)如下:
??OK,第二份數(shù)據(jù),每部電影(共20部)的主演,以《流浪地球》為例,網(wǎng)址為:https://baike.baidu.com/item/...,頁面如下:
我們只需要爬取每部電影的主演就夠了,也就是上圖中的紅色部分,實(shí)現(xiàn)的Python代碼(actor.py)如下:
# -*- coding: utf-8 -*- import requests import pandas as pd from bs4 import BeautifulSoup def get_actors(src): url = "https://baike.baidu.com"+src # 請(qǐng)求頭部 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"} r = requests.get(url, headers=headers) soup = BeautifulSoup(r.text.encode("ISO-8859-1"),"lxml") names = soup.find_all("dt", class_="basicInfo-item name") values = soup.find_all("dd", class_="basicInfo-item value") actors = [] for name, value in zip(names, values): # print(name.text) if "主" in name.text and "演" in name.text: # print(name.text.replace("????", ""), value.text) actors = value.text.strip().split(",") actors = [actor.strip().replace("xa0", "").replace(" [6]", "") for actor in actors if actor] # print(actors) return ",".join(actors) df = pd.read_csv("./movies.csv") actors_list = [] for name, src in zip(list(df["name"]), list(df["src"])): actors = get_actors(src) # print(name, actors) actors_list.append(actors) new_df = pd.DataFrame({"actors": actors_list}) new_df["name"] = df["name"] # print(new_df) new_df.to_csv(r"./actors.csv", index=False)
??生成的actor.csv數(shù)據(jù)如下:
??OK,數(shù)據(jù)收集的任務(wù)就到此完成了,有了爬蟲,輕松搞定數(shù)據(jù)難題。
導(dǎo)入數(shù)據(jù)?? 接著,我們需要用到剛才儲(chǔ)存的movies.csv和actor.csv,利用Py2neo來將數(shù)據(jù)導(dǎo)入至Neo4j中。
?? 首先,需要確保你的電腦已安裝好Neo4j,Py2neo,并開啟了Neo4j服務(wù),具體的安裝流程可參考網(wǎng)址:https://www.w3cschool.cn/neo4... 。
?? 利用Py2neo,我們就可以用Python輕松地實(shí)現(xiàn)將數(shù)據(jù)導(dǎo)入至Neo4j,實(shí)現(xiàn)的功能為:創(chuàng)建電影節(jié)點(diǎn)以及演員節(jié)點(diǎn),并創(chuàng)建兩者之間的關(guān)系,關(guān)系名稱為“ACT_IN”。實(shí)現(xiàn)的Python代碼()如下:
# -*- coding: utf-8 -*- import pandas as pd from py2neo import Graph, Node, Relationship, NodeMatcher # 讀取csv文件 movies_df = pd.read_csv(r"./movies.csv") actors_df = pd.read_csv(r"./actors.csv") # 連接Neo4j服務(wù) graph = Graph(host="localhost://7474", auth=("neo4j", "jc147369")) # 創(chuàng)建電影節(jié) for i in range(movies_df.shape[0]): rank = str(movies_df.iloc[i, :]["rank"]) name = movies_df.iloc[i, :]["name"] box_office = movies_df.iloc[i, :]["box_office"] avg_price = str(movies_df.iloc[i, :]["avg_price"]) avg_people = str(movies_df.iloc[i, :]["avg_people"]) begin_date = movies_df.iloc[i, :]["begin_date"] node = Node("Movie", name=name, rank=rank, box_office=box_office, avg_price=avg_price, avg_people=avg_people, begin_date=begin_date ) # print(movies_df.iloc[i, :]["rank"]) graph.create(node) print("create movie nodes successfully!") # 創(chuàng)建演員節(jié)點(diǎn) all_actors = set() for i in range(actors_df.shape[0]): actor_list = actors_df.iloc[i, :]["actors"].split(",") for actor in actor_list: all_actors.add(actor) for actor in all_actors: node = Node("Actor", name=actor) graph.create(node) print("create actor nodes successfully!") # 創(chuàng)建演員——電影關(guān)系 for i in range(actors_df.shape[0]): name = actors_df.iloc[i, :]["name"] matcher = NodeMatcher(graph) movie_node = matcher.match("Movie", name=name).first() actors = actors_df.iloc[i, :]["actors"].split(",") # print(name, actors) for actor in actors: actor_node = matcher.match("Actor", name=actor).first() relationship = Relationship(actor_node, "ACT_IN", movie_node) graph.create(relationship) print("create relationships successfully!") print("You can check Neo4j now!")
??只要你的電腦已安裝好Neo4j,Py2neo,并開啟了Neo4j服務(wù),不出意外,那么你的Neo4j已經(jīng)默默地儲(chǔ)存了這些數(shù)據(jù),而它們將會(huì)給出帶來巨大的驚喜:天吶,這竟然是個(gè)數(shù)據(jù)庫!
??在瀏覽器中輸入“l(fā)ocalhost:7474”,并點(diǎn)擊左上方的數(shù)據(jù)庫圖標(biāo),就能看到下圖:
??可以看到,在Neo4j中,我們創(chuàng)建了142個(gè)節(jié)點(diǎn),分為兩類:Movie和Actor,以及136對(duì)關(guān)系,關(guān)系名稱為ACT_IN. 當(dāng)然,這些都是枯燥的,那么我們來看看數(shù)據(jù)展示這步吧,它會(huì)給我們帶來什么驚喜?
數(shù)據(jù)展示??好不容易到了數(shù)據(jù)展示這一步,之前的努力都不會(huì)白費(fèi)!
??在Neo4j的前端頁面(也就是網(wǎng)址:http://localhost:7474)中的命令行中輸入命令:
MATCH (Movie) RETURN (Movie);
運(yùn)行命令后,很快就能得到整個(gè)圖(包含電影節(jié)點(diǎn)、演員節(jié)點(diǎn)以及關(guān)系)的可視化展示,由于圖像過大,不能看清細(xì)節(jié),因此,就局部放大來看,同時(shí)得到一些簡單的分析。
??首先是圖一,吳京主演的電影。
在中國電影票房排行榜的前20名中,吳京主演了《戰(zhàn)狼2》與《流浪地球》,且兩者沒有其他更多的相同主演。
??接著是圖二,沈騰主演的電影。
在中國電影票房排行榜的前20名中,沈騰主演了《西虹市首富》、《瘋狂的外星人》以及《羞羞的鐵拳》,這顯示了沈騰的票房號(hào)召力(他也是筆者喜歡的喜劇演員),不過開心麻花團(tuán)隊(duì)的其他成員在這三部電影的拍攝中應(yīng)該見不到面。
??接著是圖三,《捉妖記》及《捉妖記2》。
捉妖記系列電影無疑是成功的,兩部電影都進(jìn)了票房的前20,他們的共同主演就多了,有曾志偉,吳君如,井柏然,白百何。
??接著是圖四,主要是看看Neo4j幫我們挖掘了哪些潛在的關(guān)系。
從《唐人街探案2》到《捉妖記2》,這個(gè)不算長的鏈條給了我們一些驚喜,原來,劉昊然可以通過尚語賢再通過曾志偉認(rèn)識(shí)李宇春,一個(gè)very interesting的分析。當(dāng)然,這個(gè)是筆者的分析,他倆到底認(rèn)不認(rèn)識(shí)筆者是不知道滴~
??分析到此結(jié)束,如果讀者想看原圖,可以參看該項(xiàng)目的github地址:https://github.com/percent4/N... 。
總結(jié)??感謝讀者不厭其煩地看到了這里,看完了這篇“又臭又長”的文章,好在圖比較多,應(yīng)該能稍微減輕點(diǎn)閱讀的壓力。
??再說說該項(xiàng)目的不足之處:那就是Neo4j的操作語法展示的比較少,約等于沒有,這主要是筆者也是初入門,不熟。如果后續(xù)對(duì)Neo4j的操作語法CQL熟練了,我們就能能到更多有趣的結(jié)果,而不是這么一句簡單的分析(有敷衍的嫌疑)。
??最后,對(duì)此項(xiàng)目感興趣的讀者,可以移步該項(xiàng)目的github地址:https://github.com/percent4/N... 。
注意:不妨了解下筆者的微信公眾號(hào): Python爬蟲與算法(微信號(hào)為:easy_web_scrape), 歡迎大家關(guān)注~
參考文獻(xiàn)Neo4j_百度百科:https://baike.baidu.com/item/...
neo4j教程:https://www.w3cschool.cn/neo4...
The Py2neo v3 Handbook: https://py2neo.org/v3/index.html
Neo4j簡介及Py2Neo的用法: https://cuiqingcai.com/4778.html
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/43256.html
摘要:圖數(shù)據(jù)庫現(xiàn)已涌現(xiàn)出許多出眾的軟件,比如筆者寫過的文章入門之中國電影票房排行淺析中的,為進(jìn)行關(guān)系數(shù)據(jù)分析而構(gòu)建的,高度可擴(kuò)展的分布式圖數(shù)據(jù)庫以及的開源圖數(shù)據(jù)庫等。 圖數(shù)據(jù)庫 ??在如今數(shù)據(jù)庫群雄逐鹿的時(shí)代中,非關(guān)系型數(shù)據(jù)庫(NoSQL)已經(jīng)占據(jù)了半壁江山,而圖數(shù)據(jù)庫(Graph Database)更是攻城略地,成為其中的佼佼者。??所謂圖數(shù)據(jù)庫,它應(yīng)用圖理論(Graph Theory)可...
摘要:另外由于豆瓣上一些電影評(píng)分?jǐn)?shù)量太少而不顯示,所以這里的電影數(shù)量會(huì)和票房數(shù)量有所差異。月度票房將類型片的票房按月劃分,得到了這張圖。 去年末的時(shí)候,我招收了新的 實(shí)訓(xùn)生 。本文是其中一位 @齊大圣 同學(xué)在實(shí)訓(xùn)兩個(gè)月時(shí)完成的項(xiàng)目案例。(碼上行動(dòng)群里同學(xué)應(yīng)該都看過這個(gè)名字,現(xiàn)在也是助教之一。)項(xiàng)目最初的想法是, 從互聯(lián)網(wǎng)上的公開信息中采集2018年在國內(nèi)上映電影的票房、評(píng)分、類型、演員等信息...
摘要:為了方便廣大的開發(fā)者,特此統(tǒng)計(jì)了網(wǎng)上諸多的免費(fèi),為您收集免費(fèi)的接口服務(wù),做一個(gè)的搬運(yùn)工,以后會(huì)每月定時(shí)更新新的接口。將長段中文切詞分開。 為了方便廣大的開發(fā)者,特此統(tǒng)計(jì)了網(wǎng)上諸多的免費(fèi)API,為您收集免費(fèi)的接口服務(wù),做一個(gè)api的搬運(yùn)工,以后會(huì)每月定時(shí)更新新的接口。有些接口來自第三方,在第三方注冊(cè)就可以成為他們的會(huì)員,免費(fèi)使用他們的部分接口。 百度AccessToken:針對(duì)HTTP ...
閱讀 3174·2023-04-25 19:09
閱讀 3885·2021-10-22 09:54
閱讀 1757·2021-09-29 09:35
閱讀 2914·2021-09-08 09:45
閱讀 2256·2021-09-06 15:00
閱讀 2773·2019-08-29 15:32
閱讀 1038·2019-08-28 18:30
閱讀 375·2019-08-26 13:43