2014-09-26 58 views
-1

這個練習的目標是生成一個圖表作爲該頁面中的特定部分:(http://www.realclearpolitics.com/epolls/2012/president/us/general_election_romney_vs_obama-1171.html我不能明白的代碼

用於生成這樣的圖上的數據被存儲爲XML頁,網址如: http://charts.realclearpolitics.com/charts/[id].xml 這裏,[id]是一個唯一的整數,位於顯示圖形的頁面的URL的末尾。奧巴馬,羅姆尼的比賽ID是1171:

import re 

def get_poll_xml(poll_id): 
    url ="http://charts.realclearpolitics.com/charts/%i.xml" %int(poll_id) 
    return requests.get(url).text 

def _strip(s): # function to remove characters 
    return re.sub(r'[\W_]+', '', s) 

def plot_colors(xml): 
    ''' 
    Given an XML document like the link above, returns a python dictionary 
    that maps a graph title to a graph color. 

    Both the title and color are parsed from attributes of the <graph> tag: 
    <graph title="the title", color="#ff0000"> -> {'the title': '#ff0000'} 
    ''' 
    dom = web.Element(xml) 
    result = {} 
    for graph in dom.by_tag('graph'): 
     title = _strip(graph.attributes['title']) 
     result[title] = graph.attributes['color'] 
    return result 

def rcp_poll_data(xml): 
    """ 
    A pandas DataFrame with the following columns: 
    date: The date for each entry 
    title_n: The data value for the gid=n graph 

    This DataFrame should be sorted by date 

    Example 
    ------- 
    Consider the following simple xml page: 

    <chart> 
    <series> 
    <value xid="0">1/27/2009</value> 
    <value xid="1">1/28/2009</value> 
    </series> 
    <graphs> 
    <graph gid="1" color="#000000" balloon_color="#000000" title="Approve"> 
    <value xid="0">63.3</value> 
    <value xid="1">63.3</value> 
    </graph> 
    <graph gid="2" color="#FF0000" balloon_color="#FF0000" title="Disapprove"> 
    <value xid="0">20.0</value> 
    <value xid="1">20.0</value> 
    </graph> 
    </graphs> 
    </chart> 

    Given this string, rcp_poll_data should return 
    result = pd.DataFrame({'date': pd.to_datetime(['1/27/2009', '1/28/2009']), 
         'Approve': [63.3, 63.3], 'Disapprove': [20.0, 20.0]}) 
    """ 
    dom = web.Element(xml) 
    result = {}   

    dates = dom.by_tag('series')[0]  
    dates = {n.attributes['xid']: str(n.content) for n in dates.by_tag('value')} 

    keys = dates.keys() 
    result['date'] = pd.to_datetime([dates[k] for k in keys]) 

    for graph in dom.by_tag('graph'): 
     name = graph.attributes['title'] 
     data = {n.attributes['xid']: float(n.content) if n.content else np.nan for n in graph.by_tag('value') } 
     keyl = data.keys()  
     result[name] = [data[k]for k in keyl] 

    result = pd.DataFrame(result) 
    result = result.sort(columns=['date']) 

    return result 

def poll_plot(poll_id): 
    xml = get_poll_xml(poll_id) 
    data = rcp_poll_data(xml) 
    colors = plot_colors(xml) 

    #remove characters like apostrophes 
    data = data.rename(columns = {c: _strip(c) for c in data.columns}) 

    #normalize poll numbers so they add to 100%  
    norm = data[colors.keys()].sum(axis=1)/100  
    for c in colors.keys(): 
     data[c] /= norm 

    for label, color in colors.items(): 
     plt.plot(data.date, data[label], color=color, label=label)   

    plt.xticks(rotation=70) 
    plt.legend(loc='best') 
    plt.xlabel("Date") 
    plt.ylabel("Normalized Poll Percentage") 

poll_plot(1044) 
plt.title("Obama Job Approval") 

在上述代碼中,我不可能瞭解以下部分,可有人給我解釋一下。我完全失去了。

data = data.rename(columns = {c: _strip(c) for c in data.columns}) 

#normalize poll numbers so they add to 100%  
norm = data[colors.keys()].sum(axis=1)/100  
for c in colors.keys(): 
    data[c] /= norm 

for label, color in colors.items(): 
    plt.plot(data.date, data[label], color=color, label=label) 
+0

我認爲之前有人從事過它。也許這篇文章可能會幫助你http://stackoverflow.com/questions/19343016/parse-through-an-xml-in-python – 2014-09-26 03:28:39

+0

不,但它不能解決我的問題。我無法理解我的代碼的某個部分。但解析的例子完全不同 – MJP 2014-09-26 03:31:17

+0

「你能爲我解釋這個代碼嗎」並不是一個好的SO問題。我們需要聽聽爲什麼你不理解它,尤其是你不瞭解的,也許更重要的是你爲什麼*擁有你所不瞭解的所有代碼。 :)我的意思是,你遇到麻煩的代碼對我來說看起來並不複雜,其餘的你沒有問題... – 2014-09-26 04:16:24

回答

1

你在評論中說你想知道什麼意思/=。它被稱爲增強分配並在PEP 203中定義。

你有一個INT var和希望值總和爲它

n = 1 
n = n + 1 
print n 
2 

這裏是一個優化的方式來做到這一點

n = 1 
n += 1 

正是在循環

使用起來非常有用
n = 1 
while n < 10: 
    n += 1 

print n 
10 

所以用/=你正在使用操盤添加

n = 4 
n /= 2 
print n 
2 

n = 10 
while n > 2: 
    n /= 2 

print n 
2 

欲瞭解更多信息有關增強Assignement看看Wikepedia項。

+0

明白了:)。你能否解釋一下。標題= [str(t.content).split('(')[0] .strip()for t in headers [3:-1]] ...我知道什麼('(')[0]'意思是 - – MJP 2014-09-28 12:29:13

+0

在控制檯上試試'print'123(456(789'.split('(')[0]'and you) 'll understand。 – 2014-09-29 15:37:16

+0

明白了,split函數返回一個列表並且split [0]返回列表中的第一個元素 – MJP 2014-09-30 08:09:15

0

如果您想知道語法data[c] /= norm的含義,它與更常見的+=運算符類似。它佔據作業左側的左側,並將其指定爲左側值除以右側值。它相當於data[c] = data[c]/norm。例如

x = 6.0 
x /= 2.0 

現在x將有3.0

值,請儘量在什麼你問你的問題,並呼喚你不理解的代碼的特定部分更加清晰。

+0

@ JacobBower-我很新的堆棧流。對於答案,你還可以解釋一下。header = table.by_tag('th') labels = [str(t.content).split('(')[0] .strip()for t in headers [3: -1]] ...我知道split和strip是什麼意思,但是deos split('(')[0]意味着什麼? – MJP 2014-09-28 12:27:15