2016-02-16 14 views
2

我正在嘗試構建一個數據庫,其中包含玩遊戲數據的數個賽季的NBA比賽,對於我的Msc。在經濟學論文。目前,我提取NBA的API(see example)和分裂每場比賽場比賽使用this routine不同以.json文件(正式適用於PBP目的),從而產生以.json文件,(第一個玩的例子):按照特定的.json轉換NBA比賽爲.csv

{"headers": ["GAME_ID", "EVENTNUM", "EVENTMSGTYPE", "EVENTMSGACTIONTYPE", "PERIOD", "WCTIMESTRING", "PCTIMESTRING", "HOMEDESCRIPTION", "NEUTRALDESCRIPTION", "VISITORDESCRIPTION", "SCORE", "SCOREMARGIN"], "rowSet": [["0041400406", 0, 12, 0, 1, "9:11 PM", "12:00", null, null, null, null, null], ["0041400406", 1, 10, 0, 1, "9:11 PM", "12:00", "Jump Ball Mozgov vs. Green: Tip to Barnes", null, null, null, null] 

我計劃在創建一個循環將所有生成的.json文件轉換爲.csv,這樣它就可以進行stata中的計量經濟學分析。目前,我陷入了這個過程的第一步:創建json到CSV轉換過程(之後我將設計循環)。我想的代碼是:

f = open('pbp_0041400406.json') 
data = json.load(f) 
f.close() 

with open("pbp_0041400406.csv", "w") as file: 
    csv_file = csv.writer(file) 

    for rowSet in data: 
     csv_file.writerow(rowSet) 

f.close() 

然而,產生CSV文件顯示尷尬的結果:一個線讀取h,e,a,d,e,r,s和其他閱讀r,o,w,S,e,t,因此不會捕捉標題或行集(戲劇本身)。

我試圖解決這個問題,考慮到貢獻on this thread,但我一直無法做到這一點。任何人都可以提供一些解決這個問題的見解嗎?

[編輯]用原始代碼中的數據替換行集也取得了相同的結果。

在此先感謝!

+0

嗨@SNygard,謝謝你的提示。我打印rowSet,它的名字沒有定義。打印數據後,原始的.json文件確實顯示在外殼上。但是,在替換原始代碼中的rowset數據之後,返回的.csv獲得與以前相同的結果。 –

+2

考慮到示例JSON,'data'將會是一個[dict](https://docs.python.org/2/tutorial/datastructures.html#dictionaries),帶有兩個鍵'headers'和'rowSet'。因此,循環訪問行需要用於數據行['rowSet']'。 –

回答

-1

問題解決了!使用@MaxU代碼和先前構建的包含所有gameid的.CSV,從01-02賽季開始的每個nba遊戲都可以通過.JSON直接抓取並使用以下代碼轉換爲CSV:(Credits for @MaxU)

from __future__ import print_function 

import json 
import csv 
import requests 

u_a = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36" 
url_pattern = "http://stats.nba.com/stats/playbyplayv2?GameID=%(GameID)s&StartPeriod=%(StartPeriod)s&EndPeriod=%(EndPeriod)s&tabView=%(tabView)s" 


def write_csv(game_id, resultSet): 
fn = resultSet['name'] + '_' + str(game_id) + '.csv' 
# ignore unimportant resultsets ... 
if resultSet['name'] not in ['PlayByPlay', 'PlayBlahBlah']: 
    return 
with open(fn, 'w') as fout: 
    csv_file = csv.writer(fout, quotechar='"') 

    csv_file.writerow(resultSet['headers']) 

    for rowSet in resultSet['rowSet']: 
     csv_file.writerow(rowSet) 

def process_game_id(game_id, tabView='playbyplay', 
       start_period='0', end_period='0'): 
url_parms = { 
    'GameID': game_id, 
    'StartPeriod': start_period, 
    'EndPeriod': end_period, 
    'tabView': tabView, 
} 

r = requests.get((url_pattern % url_parms), headers={"USER-AGENT":u_a}) 

if r.status_code == requests.codes.ok: 
    data = json.loads(r.text) 

    for rset in data['resultSets']: 
     write_csv(url_parms['GameID'], rset) 
else: 
    r.raise_for_status() 


if __name__ == '__main__': 
# 
# assuming that the 'games.csv' file contains all Game_IDs ... 
# 
with open('games.csv', 'r') as f: 
    csv_reader = csv.reader(f, delimiter=',') 
    for row in csv_reader: 
     process_game_id(row[<column_num_containing_Game_ID>]) 

對這個數據有任何進一步的問題,PLZ做PM我。快樂編碼每個人!

2

試試這個:

import json 
import csv 

with open('json.json') as f: 
    data = json.load(f) 


with open("pbp_0041400406.csv", "w") as fout: 
    csv_file = csv.writer(fout, quotechar='"') 

    csv_file.writerow(data['headers']) 

    for rowSet in data['rowSet']: 
     csv_file.writerow(rowSet) 

得到的CSV:

GAME_ID,EVENTNUM,EVENTMSGTYPE,EVENTMSGACTIONTYPE,PERIOD,WCTIMESTRING,PCTIMESTRING,HOMEDESCRIPTION,NEUTRALDESCRIPTION,VISITORDESCRIPTION,SCORE,SCOREMARGIN 

0041400406,0,12,0,1,9:11 PM,12:00,,,,, 

0041400406,1,10,0,1,9:11 PM,12:00,Jump Ball Mozgov vs. Green: Tip to Barnes,,,, 
+0

Hi @MaxU,謝謝你的回覆!我試圖重複它,並且我成功地製作了我正在尋找的.CSV文件。但是,現在我正在努力解決另一個問題,因爲我需要將此代碼循環到同一目錄中的多個文件。 這個想法是運行一些相同的確切代碼。JSON文件在同一路徑中,而不管它們的名稱/順序/等等。 我已經嘗試了一些解決方法,使用'while'和'for'代碼創建對象,但迄今爲止失敗。你對這個問題有什麼建議嗎? –

+0

你見過我的第二個回答:http://stackoverflow.com/a/35445623/5741205 – MaxU

1

我想你可能已經作出關於JSON輸入的結構是錯誤的。頂層有三個鍵。 resultSets - >列表,其第一個元素是具有鍵「rowSet」的字典。這就是我想你想要迭代的。

f = open('playbyplay', 'r') 
data = json.load(f) 
f.close() 
print data.keys() 
rows = data['resultSets'][0]['rowSet'] 

with open("pbp_0041400406.csv", "w") as file: 
    csv_file = csv.writer(file) 
    for rowSet in rows: 
     csv_file.writerow(rowSet) 

輸出數據:

0041300402,0,12,0,1,8:13 PM,12:00,,,,,,0,0,,,,,,0,0,,,,,,0,0,,,,, 
0041300402,1,10,0,1,8:13 PM,12:00,Jump Ball Duncan vs. Bosh: Tip to Wade,,,,,4,1495,Tim Duncan,1610612759,San Antonio,Spurs,SAS,5,2547,Chris Bosh,1610612748,Miami,Heat,MIA,5,2548,Dwyane Wade,1610612748,Miami,Heat,MIA 
0041300402,2,5,2,1,8:13 PM,11:45,Green STEAL (1 STL),,James Lost Ball Turnover (P1.T1),,,5,2544,LeBron James,1610612748,Miami,Heat,MIA,4,201980,Danny Green,1610612759,San Antonio,Spurs,SAS,0,0,,,,, 
0041300402,3,1,1,1,8:14 PM,11:26,Green 18' Jump Shot (2 PTS) (Splitter 1 AST),,,0 - 2,2,4,201980,Danny Green,1610612759,San Antonio,Spurs,SAS,4,201168,Tiago Splitter,1610612759,San Antonio,Spurs,SAS,0,0,,,,, 
0041300402,4,6,2,1,8:14 PM,11:03,Green S.FOUL (P1.T1),,,,,4,201980,Danny Green,1610612759,San Antonio,Spurs,SAS,5,1740,Rashard Lewis,1610612748,Miami,Heat,MIA,1,0,,,,, 
0041300402,5,3,11,1,8:14 PM,11:03,,,Lewis Free Throw 1 of 2 (1 PTS),1 - 2,1,5,1740,Rashard Lewis,1610612748,Miami,Heat,MIA,0,0,,,,,,0,0,,,,, 
0041300402,7,3,12,1,8:14 PM,11:03,,,MISS Lewis Free Throw 2 of 2,,,5,1740,Rashard Lewis,1610612748,Miami,Heat,MIA,0,0,,,,,,0,0,,,,, 
0041300402,9,4,0,1,8:15 PM,11:01,Splitter REBOUND (Off:0 Def:1),,,,,4,201168,Tiago Splitter,1610612759,San Antonio,Spurs,SAS,0,0,,,,,,0,0,,,,, 
0041300402,10,1,5,1,8:15 PM,10:52,Duncan 1' Layup (2 PTS) (Parker 1 AST),,,1 - 4,3,4,1495,Tim Duncan,1610612759,San Antonio,Spurs,SAS,4,2225,Tony Parker,1610612759,San Antonio,Spurs,SAS,0,0,,,,, 
+0

嗨@MaxU,謝謝你的回覆!我試圖重複它,並且我成功地生成了我正在查找的.CSV文件,但只有當我使用原始.json提要時。但是,現在我正在努力解決另一個問題,因爲我需要將此代碼循環到同一目錄中的多個文件。這個想法是在相同路徑上的許多.JSON文件上運行相同的確切代碼,而不考慮它們的名稱/順序等。我已經嘗試了一些解決方法,使用'while'和'for'代碼創建對象,但迄今爲止失敗。你對這個問題有什麼建議嗎? –