发生异常:TypeError:只能将size-1数组转换为Python标量

时间:2019-01-10 14:44:49

标签: python pandas matplotlib

这是我在这里的第一篇文章。 我正在用Python做一个关于Football Scores统计和预测的项目。 我从this project那里得到了想法,并试图重新创建它,但这给了我一个错误,例如 this

我正在为自己的需要重新编写代码,但是即使我复制并粘贴了原始代码,也给我同样的错误,而在原始帖子中似乎一切正常。

这是代码中包含以下内容的部分:

ax1.bar(chel_home.index-0.4,chel_home.values,width=0.4,color="#034694",label="Chelsea")

它只是说“只能将size-1数组转换为Python标量”,但是我真的不知道问题出在哪里,因为那是我使用Python的第一种方法。

完整的代码是这样的:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn
from scipy.stats import poisson,skellam

epl_1617 = pd.read_csv("http://www.football-data.co.uk/mmz4281/1617/E0.csv")
epl_1617 = epl_1617[['HomeTeam','AwayTeam','FTHG','FTAG']]
epl_1617 = epl_1617.rename(columns={'FTHG': 'HomeGoals', 'FTAG': 'AwayGoals'})
epl_1617.head()

epl_1617 = epl_1617[:-10]
epl_1617.mean()

    # construct Poisson  for each mean goals value
poisson_pred = np.column_stack([[poisson.pmf(i, epl_1617.mean()[j]) for i in range(8)] for j in range(2)])

# plot histogram of actual goals
plt.hist(epl_1617[['HomeGoals', 'AwayGoals']].values, range(9), 
         alpha=0.7, label=['Home', 'Away'],normed=True, color=["#FFA07A", "#20B2AA"])

# add lines for the Poisson distributions
pois1, = plt.plot([i-0.5 for i in range(1,9)], poisson_pred[:,0],
                  linestyle='-', marker='o',label="Home", color = '#CD5C5C')
pois2, = plt.plot([i-0.5 for i in range(1,9)], poisson_pred[:,1],
                  linestyle='-', marker='o',label="Away", color = '#006400')

leg=plt.legend(loc='upper right', fontsize=13, ncol=2)
leg.set_title("Poisson           Actual        ", prop = {'size':'14', 

'weight':'bold'})

    plt.xticks([i-0.5 for i in range(1,9)],[i for i in range(9)])
    plt.xlabel("Goals per Match",size=13)
    plt.ylabel("Proportion of Matches",size=13)
    plt.title("Number of Goals per Match (EPL 2016/17 Season)",size=14,fontweight='bold')
    plt.ylim([-0.004, 0.4])
    plt.tight_layout()
    plt.show()

    # probability of draw between home and away team
    skellam.pmf(0.0,  epl_1617.mean()[0],  epl_1617.mean()[1])

    # probability of home team winning by one goal
    skellam.pmf(1,  epl_1617.mean()[0],  epl_1617.mean()[1])

    skellam_pred = [skellam.pmf(i,  epl_1617.mean()[0],  epl_1617.mean()[1]) for i in range(-6,8)]

plt.hist(epl_1617[['HomeGoals']].values - epl_1617[['AwayGoals']].values, range(-6,8), 
         alpha=0.7, label='Actual',normed=True)
plt.plot([i+0.5 for i in range(-6,8)], skellam_pred,
                  linestyle='-', marker='o',label="Skellam", color = '#CD5C5C')
plt.legend(loc='upper right', fontsize=13)
plt.xticks([i+0.5 for i in range(-6,8)],[i for i in range(-6,8)])
plt.xlabel("Home Goals - Away Goals",size=13)
plt.ylabel("Proportion of Matches",size=13)
plt.title("Difference in Goals Scored (Home Team vs Away Team)",size=14,fontweight='bold')
plt.ylim([-0.004, 0.26])
plt.tight_layout()
plt.show()

直到现在为止它都可以正常工作,然后是部分错误提示我

fig,(ax1,ax2) = plt.subplots(2, 1)


chel_home = epl_1617[epl_1617['HomeTeam']=='Chelsea'][['HomeGoals']].apply(pd.value_counts,normalize=True)
chel_home_pois = [poisson.pmf(i,np.sum(np.multiply(chel_home.values.T,chel_home.index.T),axis=1)[0]) for i in range(8)]
sun_home = epl_1617[epl_1617['HomeTeam']=='Sunderland'][['HomeGoals']].apply(pd.value_counts,normalize=True)
sun_home_pois = [poisson.pmf(i,np.sum(np.multiply(sun_home.values.T,sun_home.index.T),axis=1)[0]) for i in range(8)]

chel_away = epl_1617[epl_1617['AwayTeam']=='Chelsea'][['AwayGoals']].apply(pd.value_counts,normalize=True)
chel_away_pois = [poisson.pmf(i,np.sum(np.multiply(chel_away.values.T,chel_away.index.T),axis=1)[0]) for i in range(8)]
sun_away = epl_1617[epl_1617['AwayTeam']=='Sunderland'][['AwayGoals']].apply(pd.value_counts,normalize=True)
sun_away_pois = [poisson.pmf(i,np.sum(np.multiply(sun_away.values.T,sun_away.index.T),axis=1)[0]) for i in range(8)]

ax1.bar(chel_home.index-0.4,chel_home.values,width=0.4,color="#034694",label="Chelsea")
ax1.bar(sun_home.index,sun_home.values,width=0.4,color="#EB172B",label="Sunderland")
pois1, = ax1.plot([i for i in range(8)], chel_home_pois,
                  linestyle='-', marker='o',label="Chelsea", color = "#0a7bff")
pois1, = ax1.plot([i for i in range(8)], sun_home_pois,
                  linestyle='-', marker='o',label="Sunderland", color = "#ff7c89")
leg=ax1.legend(loc='upper right', fontsize=12, ncol=2)
leg.set_title("Poisson                 Actual                ", prop = {'size':'14', 'weight':'bold'})
ax1.set_xlim([-0.5,7.5])
ax1.set_ylim([-0.01,0.65])
ax1.set_xticklabels([])
# mimicing the facet plots in ggplot2 with a bit of a hack
ax1.text(7.65, 0.585, '                Home                ', rotation=-90,
        bbox={'facecolor':'#ffbcf6', 'alpha':0.5, 'pad':5})
ax2.text(7.65, 0.585, '                Away                ', rotation=-90,
        bbox={'facecolor':'#ffbcf6', 'alpha':0.5, 'pad':5})

ax2.bar(chel_away.index-0.4,chel_away.values,width=0.4,color="#034694",label="Chelsea")
ax2.bar(sun_away.index,sun_away.values,width=0.4,color="#EB172B",label="Sunderland")
pois1, = ax2.plot([i for i in range(8)], chel_away_pois,
                  linestyle='-', marker='o',label="Chelsea", color = "#0a7bff")
pois1, = ax2.plot([i for i in range(8)], sun_away_pois,
                  linestyle='-', marker='o',label="Sunderland", color = "#ff7c89")
ax2.set_xlim([-0.5,7.5])
ax2.set_ylim([-0.01,0.65])
ax1.set_title("Number of Goals per Match (EPL 2016/17 Season)",size=14,fontweight='bold')
ax2.set_xlabel("Goals per Match",size=13)
ax2.text(-1.15, 0.9, 'Proportion of Matches', rotation=90, size=13)
plt.tight_layout()
plt.show()

这里应该出现另一个图,但是它只是说:“只能将size-1数组转换为Python标量”。

我真的不知道该怎么办,而且我开始发疯了,所以我真的希望您能帮助我。 预先谢谢您,祝大家愉快!

1 个答案:

答案 0 :(得分:1)

问题在于,条形图的数组是2d数组,必须将它们展平。使用.flatten()可以轻松完成此操作,该操作会将代码中的2d数组转换为1d数组。如果您查看chel_home.values,看起来就像

array([[0.33333333],
       [0.22222222],
       [0.22222222],
       [0.16666667],
       [0.05555556]])

您需要的是

array([0.33333333, 0.22222222, 0.22222222, 0.16666667, 0.05555556])

只需用以下几行替换代码中的绘图命令

ax1.bar(chel_home.index-0.4,chel_home.values.flatten(),width=0.4,color="#034694",label="Chelsea")
ax1.bar(sun_home.index, sun_home.values.flatten(),width=0.4,color="#EB172B",label="Sunderland")

ax2.bar(chel_away.index-0.4,chel_away.values.flatten(),width=0.4,color="#034694",label="Chelsea")
ax2.bar(sun_away.index,sun_away.values.flatten(),width=0.4,color="#EB172B",label="Sunderland")

您也可以使用.ravel()代替.flatten()

enter image description here