Python 为 FPL(!)数据分析
使用 Python 和 Matplotlib 进行虚拟足球数据分析和可视化
作者图表
介绍
这个作品有两个原因:(1)我想用 Python 自学一些数据分析和可视化技术;(2)我需要阻止我的梦幻足球队下滑几个排行榜。但首先,感谢大卫·艾伦提供了关于访问梦幻英超 API 的有用指南,可以在这里找到。
首先,我们需要设置我们的笔记本以使用 Pandas 和 Matplotlib(为此我使用 Jupyter),并连接到 Fantasy Premier League API 以访问分析所需的数据。
#Notebook Config
import requests
import pandas as pd
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('ggplot')#API Set-Up
url = '[https://fantasy.premierleague.com/api/bootstrap-static/'](https://fantasy.premierleague.com/api/bootstrap-static/')
r = requests.get(url)
json = r.json()
然后,我们可以建立我们的熊猫数据框架(想想数据表),它将被查询以获得有价值的见解——希望如此。我们创建的每个数据帧(_df)都与一个可通过 FPL API 访问的 JSON 数据结构相关。要获得完整的列表,运行 json.keys() 。我们对“元素”(球员数据)、“元素类型”(位置参考)和“球队”感兴趣。
elements_df = pd.DataFrame(json['elements'])
element_types_df = pd.DataFrame(json['element_types'])
teams_df = pd.DataFrame(json['teams'])
默认情况下, elements_df 包含许多我们现在不感兴趣的列(关于每个数据帧的概述,请参阅 David 的文章)。我创建了一个新的 DataFrame — main_df — ,其中包含我可能想要使用的列。
main_df = elements_df[['web_name','first_name','team','element_type','now_cost','selected_by_percent','transfers_in','transfers_out','form','event_points','total_points','bonus','points_per_game','value_season','minutes','goals_scored','assists','ict_index','clean_sheets','saves']]
需要注意的是 elements_df 使用键来引用球员的位置和球队等信息。例如,在’ element_type ’ 列中,值为“1”=守门员,在 ’ 列中,值为“1”=阿森纳。这些是对我们创建的另外两个数据帧的引用( *element_types_df,*和 teams_df)
如果我们预览 element_types_df ,我们会看到这里的每个“id”号对应一个位置:
element_types_df.head()
作者的表格输出
在 teams_df 中,“id”对应每个团队名称:
teams_df.head()
作者的表格输出
在这一点上,我们还可以看到没有一个团队的统计数据被更新,这可能是一个稍后的问题——我特别希望每个团队玩的游戏。为了节省时间和/或缺乏更好的解决方案,我通过以下方式手动添加数据:(1)创建一个新字典,(2)将其转换为两列数据帧,(3)用我创建的数据覆盖 teams_df 中的“已播放”列。
#create new dictionary
games_played = [['Arsenal','4'], ['Aston Villa','3'], ['Brighton','4'], ['Burnley','3'], ['Chelsea','4'], ['Crystal Palace','4'], ['Everton','4'], ['Fulham','4'], ['Leicester','4'], ['Leeds','4'], ['Liverpool','4'], ['Man City','3'], ['Man Utd','3'], ['Newcastle','4'], ['Sheffield Utd','4'], ['Southampton','4'], ['Spurs','4'], ['West Brom','4'], ['West Ham','4'], ['Wolves','4']]#turn into a DataFrame
played_df = pd.DataFrame(games_played,columns=['team','games_played'])#overwrite existing DataFrame column
teams_df['played'] = played_df['games_played'].astype(str).astype(int)#voila
teams_df.head()
作者的表格输出
出于我们分析的目的,我们将使用实际的位置和团队名称,而不是数字标识符。为了避免以后引用不同地方的数据,我们现在可以将我们的数据帧合并在一起,形成一种“主”表。我们将使用 main_df 作为基础,使用 pd.merge 来执行到其他数据帧、 elements_types_df 和 teams_df 的连接。
这里有三个要素:
- 使用 pd.merge ,其中 " left_on =" 获取我们要加入的 main_df 中的唯一标识符。 " right_on =" 是我们要连接的目标数据帧中的等效列(在这两种情况下, ’ id ’ )。例如 main _ df[’ element _ type ‘]= element _ types _ df[’ id ‘],但我们实际上想在 display 中使用 element _ types _ df[’ singular _ name ']。我们使用 " 右 =" 来列出我们正在跨越的每一列。
#merging elements_types_df onto main_df
main_df = pd.merge(left=main_df,right=**elements_types_df**[['id','singular_name']],left_on='element_type', right_on='id', how='left')
2.使用 df.drop ,删除合并后不需要的列。虽然我们需要使用“id”列来连接,但我们不希望它们出现在最终的数据帧中。我们也不再需要原来的*‘element _ type’*和 ’ team ’ 列,因为我们现在已经将用户友好的数据合并到了 *main_df 中。*使用“轴=1”指定我们正在删除一列而不是一行。
main_df = main_df.drop(["id", "element_type"],axis=1)
3.使用 df.rename ,清理我们的数据帧。在 *element_types_df 中,*位置名称存储在‘singular _ name’下。我们将把它重命名为“位置”,使它更直观。
main_df = main_df.rename(columns = {'singular_name': 'position'})
要合并 teams_df 数据,我们可以调整上面的内容:
#merging teams_df onto main_df
main_df = pd.merge(left=main_df,right=**teams_df**[['id','name','played','strength_overall_away','strength_overall_home']],left_on='team', right_on='id', how='left')
main_df = main_df.drop(["id", "team"],axis=1)
main_df = main_df.rename(columns = {'name': 'team'})
最后,我们先发制人地将一些现有列转换为浮点数,以避免运行计算和排序值的潜在问题,我们创建了一个新列“total_contribution”(进球和助攻的总和):
#Additional columns stored as floats
main_df['value'] = main_df.value_season.astype(float)
main_df['ict_score'] = main_df.ict_index.astype(float)
main_df['selection_percentage'] = main_df.selected_by_percent.astype(float)
main_df['current_form'] = main_df.form.astype(float)#Total Goals Contribution column = Goals + Assists
main_df['total_contribution']= main_df['goals_scored'] + main_df['assists']
main_df 的设置,我们可以使用**。loc()** 过滤掉所有值为< 0 的玩家,以避免我们的结果被那些没有获得游戏时间的玩家歪曲:
main_df = main_df.loc[sel_df.value > 0]#preview of current state
main_df.head(3)
作者的表格输出
位置
现在,使用 groupby() 函数,我们可以按位置快速查看数据。第一个参数“position”选择要分组的列,而“as_index=False”防止该列被删除并用作索引。使用聚合函数,我们可以找到每个位置的平均值和总分。我已经用一个 roundby() 到把小数限制到两位。
position_group = np.round(main_df.groupby('position', as_index=False).aggregate({'value':np.mean, 'total_points':np.sum}), 2)position_group.sort_values('value', ascending=False)
作者的表格输出
从花费来看,守门员目前返还了最多的分数,但是他们也只占球队总分数的很小一部分。由于游戏中很多门将都是 0 分钟出场,这里就不算了(因为他们的值= 0)。许多外场球员如果在比赛还剩 5 到 10 分钟的时候替补上场,将会得到 1 分的回报,拉低了平均得分。
组
球队层面的统计数据可以给出一个大致的指示,表明哪支球队打得好,或者哪里的球员可能被低估/高估。
team_group = np.round(main_df.groupby('team', as_index=False).aggregate({'value':np.mean, 'total_points':np.sum}), 2)
team_grp_df = team_group.sort_values('value', ascending=False)
team_grp_df['games_played'] = teams_df['played']
team_grp_df.head(5)
作者的表格输出
我个人并不认为西汉姆和布莱顿的资产在这个阶段(或任何阶段)价值会排名前五。然而,我们知道有些球队——包括曼联和曼城——比其他球队少打了一场比赛。让我们通过创建一些每场价值和每场得分指标来调整这一点:
team_group = np.round(main_df.groupby('team', as_index=False).aggregate({'value':np.mean, 'total_points':np.sum}), 2)
team_grp_df = team_group
team_grp_df['games_played'] = teams_df['played']
team_grp_df['value_adjusted'] = np.round(team_grp_df['value']/teams_df['played'],2)
team_grp_df['points_adjusted'] = np.round(team_grp_df['total_points']/teams_df['played'],2)
team_grp_df.sort_values('points_adjusted',ascending=False).head(5)
作者的表格输出
即使调整了比赛,曼联和曼城也没有进入前 5 名。鉴于他们最近对热刺和莱斯特的表现,这并不奇怪。阿森纳和利物浦都在每场比赛中获得大量的分数,但他们的价值分数表明你必须为此付出代价。
让我们使用 Matplotlib 来创建这些数据的一些更好的图形表示。使用 subplot 函数,我们可以并排绘制两个图形,以便于比较。我们会将团队“价值”和“总积分”与我们根据所玩游戏创建的调整数字进行比较。
fig,axes = plt.subplots(nrows=1, ncols=2, figsize=(20,7))
plt.subplots_adjust(hspace=0.25, wspace=0.25)
team_grp_df.sort_values('value').plot.barh(ax=axes[0],x="team", y="value", subplots=True, color='#0087F1')
team_grp_df.sort_values('value_adjusted').plot.barh(ax=axes[1],x="team", y="value_adjusted", subplots=True, color='#2BBD00')
plt.ylabel("")fig,axes = plt.subplots(nrows=1, ncols=2, figsize=(20,7))
plt.subplots_adjust(hspace=0.25, wspace=0.25)
team_grp_df.sort_values('total_points').plot.barh(ax=axes[0],x="team", y="total_points", subplots=True, color='#EB2000')
team_grp_df.sort_values('points_adjusted').plot.barh(ax=axes[1],x="team", y="points_adjusted", subplots=True, color='#FF8000')
plt.ylabel("")
作者的图表:价值和总点数根据所玩游戏进行调整
阿斯顿维拉在调整了他们只打了三场比赛的事实后更加突出。看看他们的结果,不难看出为什么:1 比 0(对谢夫联特),3 比 0(对富勒姆),7 比 2(对利物浦!).显然,我们正在寻找小规模的样本,但在我们决定装载维拉的资产之前,也许要考虑到他们的两场胜利和零失球都来自于这两支本赛季场均得分最差的球队。我们能对去年冠军利物浦的比赛结果赋予多大的意义呢?
球队层面的数据只能告诉我们这么多——毕竟我们每队最多有三名球员——所以让我们缩小关注范围。我们将使用**。再次锁定** 以过滤每个位置并创建更多数据帧:
gk_df = main_df.loc[main_df.position == 'Goalkeeper']
gk_df = gk_df[['web_name','team','selection_percentage','now_cost','clean_sheets','saves','bonus','total_points','value']]def_df = main_df.loc[main_df.position == 'Defender']
def_df = def_df[['web_name','team','selection_percentage','now_cost','clean_sheets','assists','goals_scored','total_contribution','ict_score','bonus','total_points','value']]mid_df = main_df.loc[main_df.position == 'Midfielder']
mid_df = mid_df[['web_name','team','selection_percentage','now_cost','assists','goals_scored','total_contribution','ict_score','current_form','bonus','total_points','value']]fwd_df = main_df.loc[main_df.position == 'Forward']
fwd_df = fwd_df[['web_name','team','selection_percentage','now_cost','assists','goals_scored','total_contribution','ict_score','current_form','minutes','bonus','total_points','value']]
守门员
从守门员开始,我们将绘制一个简单的散点图,显示成本 v 点(“价值”指标)。Matplotlib 允许我们很容易地定制一些东西,比如绘图透明度(alpha=)、大小(figsize=)和线型(ls=)。出于本文的目的,我将保持一切一致。
ax = gk_df.plot.scatter(x='now_cost',y='total_points', alpha=.5, figsize=(20,9), title="goalkeepers: total_points v cost")
for i, txt in enumerate(gk_df.web_name):
ax.annotate(txt, (gk_df.now_cost.iat[i],gk_df.total_points.iat[i]))
plt.grid(which='both', axis='both', ls='-')
plt.show()
作者图表
在赛季初期,门将价格和总积分之间没有任何关系。麦卡锡是大量球员的季前赛价值选择,到目前为止,这一点得到了回报。马丁内斯在季前赛中被低估了,因为他是阿森纳的第二选择——他最近转会维拉给了那些把他带进来的人回报。纽卡斯尔的达洛目前在 500 万选秀权中得分最高,这令人惊讶,因为他们在四场比赛中只保持了一场零失球。还有什么解释?知道守门员每三次扑救也能得一分,我们可以用“扑救”数据重新绘图。
作者图表
看来达洛的扑救次数是大多数守门员的两倍多,这有助于解释他的总得分。这也表明他的辩护人没有给他提供多少保护。在任何情况下,不失球通常会带来更多的分数,所以我宁愿选择一个更有潜力的门将。马丁内斯和麦卡锡以更低的成本提供了更多的平衡。切尔西新签下的门迪在他的处子秀不失球中不需要任何扑救,500 万的身高有着长期的价值,如果你相信他们的防线会继续改善的话。
*他的举动没有回报那些把他带进来,让他坐冷板凳的人。我敢肯定,如果他们换成皮克福德,这些人会更加自责——皮克福德是一个竭尽全力帮助对方球队将球送入自己球门的守门员。
结论:皮克福德出局,麦卡锡/梅斯利尔进。
防守
至于后卫,我们想要不失球或者进攻威胁——理想的是两者都要。亚历山大-阿诺德和罗伯逊去年在防守方面的期望达到了顶峰,但给利兹联进了 3 个球,给阿斯顿维拉进了 7 个球,这表明了问题的存在。那么哪些后卫赛季开局不错呢?
def_df.sort_values('total_points',ascending=False).head(5)
作者的表格输出
很多人都注意到了卡斯塔涅本赛季的梦幻开局(现在有 19.2%的球队)。另一方面,西汉姆的克雷斯韦尔仍然在很大程度上被忽视了——尽管他的总得分仅为 490 万。他的 ICT 指数得分也高达 27.7,对于任何不熟悉的人来说,这代表着影响力、创造力和威胁。这本质上是衡量球员在球场两端重要时刻的投入程度。这有助于评估一名球员是否为他人创造了好机会,或者进入了他们可能得分的位置。
为了快速查看与价格相关的最高表现后卫,我将制作一个新的数据框架 topdef_df ,仅选择值>为 3 且至少有 1 个进球贡献(进球或助攻)的后卫。
topdef_df = def_df = def_df.loc[def_df.value > 3]
topdef_df = topdef_df = topdef_df.loc[def_df.total_contribution > 0]
作者图表
ICT 分数高但总分数低的球员可能运气不好,如果机会转换得更早而不是更晚,那些从分数角度看“表现不佳”的球员现在可能仍然是一支球队有价值的补充。我们能知道是否有“不幸的”防守者存在吗?我们可以尝试为 ICT 得分> 10 的捍卫者创建一个数据框架,看看谁得到了奖励,谁没有。
unluckydef_df = def_df.loc[def_df.ict_score > 10]
unluckydef_df.sort_values('ict_score', ascending=False).head(5)
作者的表格输出
作者图表
亚历山大-阿诺德(7.5 米)和罗伯逊(7.0 米)没有出现在之前的图中,因为我们过滤了值> 3。鉴于他们本赛季的缓慢开局,拥有其中任何一个的球员都会高兴地看到他们仍然是游戏中最具威胁的球员之一,应该坚持下去——尽管他们付出了代价。切尔西的詹姆斯凭借他的进攻价值进入了很多人的球队,尽管他最近在排名上落后于阿兹皮里库塔。迪格内并不便宜(6.1 米),但他在一支强大的埃弗顿队中为理查德森和卡尔弗特-勒温服务——期待他的助攻数继续增加。在“不幸”的一面,弗雷德里克斯(440 万)、艾林(450 万)和达拉斯(450 万)到目前为止都相当严重地卷入了他们的比赛,没有分数显示出来。在这样的价格下,这三个人都是很好的替补人选。
结论:迪格内和奇尔威尔看起来都比我现在的多赫蒂(590 万)更好。我还听从了一个朋友的坏建议,把斯特鲁克(4.0 米)作为替补——弗雷德里克斯/艾林/达拉斯中的任何一个都是可以承受的升级。
中场
中场球员:很可能是球队得分最多的地方。为了立即关注高水平球员,我们可以像对待后卫一样,创建另一个新的数据框架——这一次,只选择 ICT 得分> 25 且总得分> 15 的中场球员。
topmid_df = mid_df.loc[mid_df.ict_score > 25]
topmid_df = topmid_df.loc[mid_df.total_points > 15]
topmid_df.sort_values('total_points',ascending=False).head(5)
作者的表格输出
作者图表
萨拉赫(1220 万英镑)和孙正义(900 万英镑)是迄今为止仅有的证明其价格合理的大牌资产。德布鲁因和斯特林有一场比赛在手,但他们的前三场比赛没有太多表现。格里利什(710 万英镑)和罗德里格斯(780 万英镑)是目前的中层价值选择,鉴于阿斯顿维拉和埃弗顿的攻击性比赛有多少是通过他们进行的,你会期望这种情况继续下去。鲍文(6.3 米)和若日尼奥(5.2 米)看起来很有价值,尽管后者在四场比赛中进了三个点球,增加了他早期的得分回报。
但是 FPL 球员喜欢(或者忽略)哪些中场球员呢?我保持了> 15 个总点数参数不变,但是按照总体选择百分比而不是成本来绘制结果。
作者图表
作者的表格输出
鲍文再次脱颖而出——在赛季开局相当强劲之后,只有不到 2%的球员选择了他。在 FPL 语中,他实际上是一个“与众不同”的选择。拥有足够低的所有权百分比的人,如果他回报良好,他会帮助你获得排行榜位置(因为很少其他人也会获得这些分数)。很多人希望优质资产奥巴姆扬和德·布鲁因能尽快开拍。
作者图表
根据 ICT 的判断,德布鲁因的持有者可以放松一点,因为他的开局很好——伤病意味着曼城缺少一名彻头彻尾的前锋,他本可以奖励他的机会创造。如果你选择了斯特林,你可能会稍微担心他会像汤森或麦吉恩一样有威胁性(费用加倍)。在另一端,儿子和萨拉赫看起来像必须的。
结论:萨拉赫和德布鲁因可能会在本赛季余下的比赛中保持领先。我会尽快让儿子回来,在他因为一个不存在的伤被转移出去之后。引进巴恩斯和佩雷拉还没有奏效——如果他们的贡献不能迅速提高,我将根据我的预算为格里利什/罗德里格斯转会。
向前
在球场的顶端,有一些更多的惊喜,看看早期的价值来自哪里。我已经排除了每个人还没有贡献一个目标来整理剧情:
topfwd_df = fwd_df[fwd_df.total_contribution > 0]
作者的表格输出
作者图表
价格和积分之间仍然没有太大的关联。像英格斯和吉米内兹这样的中等价值球员做得还可以,不算伟大。大部分的分数似乎来自 6.0-6.5 米的关口,或者 10.0 米以上。卡尔弗特-勒温本赛季的开局令人印象深刻,他的身价从 700 万英镑稳步上升到 760 万英镑。与瓦迪、威尔逊和穆佩不同,卡尔弗特-勒温的进球也没有一个来自点球。48%的玩家现在让他加入——另外 52%的玩家不会承认他们错了,即使这会让他们付出代价(我以前见过这种情况……)。
在其他地方,即使是 1060 万,凯恩仍然提供了很多价值——直接促成了本赛季迄今为止的最多进球(9)。马夏尔和沃纳可能是最大的失望,沃纳不知何故被亚伯拉罕得分超过,这是他签约取代的前锋。
以稍微不同的东西来结束,我们可以看看 FPL 球员对球员状态的反应。每个人都提到“此刻不能错过”的状态良好的前锋。理论上,人们会希望在状态正佳的球员状态正佳的时候抓住他们。在 FPL,形式=三十天内每场比赛的平均总分数。
#Add the 'transfers_in' column from our original main_dffwd_df['transfers_in'] = main_df['transfers_in']
informfwd_df = fwd_df[fwd_df.current_form > 5]
作者图表
在一个小样本量的状态良好的球员中存在一定程度的相关性(其中状态> 5)。凯恩的低转会数量可能只是反映了他已经在许多球队开始了这个赛季的事实。基于前几场比赛,很多人选择了巴福特、瓦迪和威尔森,但仍然没有多少人喜欢西布朗的卡勒姆·罗宾逊——尽管他在对切尔西的比赛中进了两个球。人们在卡尔弗特-勒温上发言,在过去几周增加了近 300 万个团队。
结论:我一直很固执,紧紧抓住理查德·里森不放,但很明显,明智的选择是他的搭档。吉米内兹有一个不错的赛程,所以他可以暂时留下来。布鲁斯特(4.5 米)很可能会坐上我的板凳,如果他在谢菲尔德联队开局不错的话。否则,我会考虑重新平衡我的团队,引进沃特金斯或巴福特。
全部的
最后,这里是按位置排列的前 5 名价值(价值=点数/成本)玩家的视图。尽管值得记住的是,由最高“价值”球员组成的球队不会在许多排行榜上名列前茅,但这都是为了在总体预算限制下最大化积分。找到好的价值可以让你在那些能打出最大比分的球员(萨拉赫,凯恩)身上花更多的钱。
作者图表
为了绘制这个图,我使用 nlargest() 按位置制作了一个前 5 名的数据框架
top5_gk_df = gk_df.nlargest(5, 'value')
top5_def_df = def_df.nlargest(5, 'value')
top5_mid_df = mid_df.nlargest(5, 'value')
top5_fwd_df = fwd_df.nlargest(5, 'value')
通过将第一个图定义为“ax ”,然后在第二个、第三个和第四个图中引用“ax=ax ”,在同一图形上对每个数据帧进行分层之前:
ax = top5_gk_df.plot.scatter(x='value', y='total_points', color='DarkBlue', label='GK', s=top5_gk_df['value']*10, alpha=.5, figsize=(15,9), title="Top 5 Value Players by Position")
for i, txt in enumerate(top5_gk_df.web_name):
ax.annotate(txt, (top5_gk_df.value.iat[i],top5_gk_df.total_points.iat[i]))top5_def_df.plot.scatter(x='value', y='total_points', color='DarkGreen', label='DEF', s=top5_gk_df['value']*10, ax=ax)
for i, txt in enumerate(top5_def_df.web_name):
ax.annotate(txt, (top5_def_df.value.iat[i],top5_def_df.total_points.iat[i]))top5_mid_df.plot.scatter(x='value', y='total_points', color='DarkOrange', label='MID', s=top5_gk_df['value']*10, ax=ax)
for i, txt in enumerate(top5_mid_df.web_name):
ax.annotate(txt, (top5_mid_df.value.iat[i],top5_mid_df.total_points.iat[i]))top5_fwd_df.plot.scatter(x='value', y='total_points', color='DarkRed', label='FWD', s=top5_gk_df['value']*10, ax=ax)
for i, txt in enumerate(top5_fwd_df.web_name):
ax.annotate(txt, (top5_fwd_df.value.iat[i],top5_fwd_df.total_points.iat[i]))
“s=top5_gk_df[‘value’]*10”参数使每个散点图气泡的大小成为“value”列的函数。也就是说,‘价值’越大,泡沫越大。然而,鉴于规模较小,上述结果几乎可以忽略不计。
结论
以上主要是使用 Python 掌握数据帧创建、操作和图形表示的练习,但是在可视化和定制方面还有很多工作要做。从数据的角度来看,不可否认,一个赛季有三到四场比赛还为时过早,但分析数据的工具/方法将在很大程度上保持一致。随着赛季的进行,不断重新运行代码来观察事情的发展会很有趣。只需不到 1 秒钟的时间,就可以重新运行生成这里所有内容的所有代码——在 FPL 应用程序上,这无疑节省了大量时间。
Python 投资:一月晴雨表策略
深入分析。
一月气压计真的有用吗?
投资时,市场时机至关重要。一种市场理论是一月份的晴雨表,它表明一月份的表现决定了今年剩余时间的市场表现。换句话说,如果 1 月份的回报是正的,那么今年剩下的时间很可能也会是正的。我想在指数水平和部门水平上检验这个理论。这个假设在标准普尔 500、纳斯达克综合指数或罗素 2000 指数上行得通吗?这个理论在某些领域比其他领域更成功吗?此外,2020 年,我们能期待什么?该指标能应对冠状病毒爆发的影响吗?
让我们潜心研究数据,找出答案!
数据源
Python 使得获取我分析所需的数据变得非常容易。我用来获取财务数据的两个包是 Quandl 和 pandas_datareader。
Quandl 是一个包含许多数据集的金融图书馆,如果你注册的话,你可以免费访问其中的一些。通过在 Python 中安装这个包,可以直接将数据调用到 dataframe 中。以下是我如何检索 S&P 综合数据。
import pandas as pd
import numpy as np
import datetime
#For graphing
import matplotlib.pyplot as plt
%matplotlib inline# quandl for financial data
import quandl# Retrieve SP500 data from Quandl
sp = quandl.get(“YALE/SPCOMP”, authtoken=unqiue_token, collapse=”daily”)
我还使用 pandas_datareader 来获取 Yahoo Finance 数据,因为 Quandl 没有太多我要寻找的历史数据。Pandas_datareader 是一个简洁的库,允许你从网站中提取数据。下面是一个例子,我如何检索历史 NASQAD 综合价格。
import pandas_datareader as dr
df = dr.data.get_data_yahoo('^IXIC', start='1971-12-31', end = '2019-12-31')
一月份标准普尔 500 晴雨表的表现
使用耶鲁大学经济系从 1872 年至今的 S&P 综合数据,我计算了每年 1 月和 2 月到 12 月的回报率。在这 148 年中,1 月回报率为正的有 98 次。在这 98 次中,从 2 月到 12 月的回报也是正的 65 次。总体而言,一月回报成功预测全年回报的次数有 91 次,成功率为 61.49%。
下面的图 1 显示了假设成功的 91 次。根据 1 月份的数据,1933 年和 1879 年的 2-12 月回报率最高,分别为 40.6%和 37.4%。晴雨表也有助于避免市场损失。例如,在 2008 年、1907 年和 1917 年,该指标为负,暗示不要投资。在那几年,市场实际上跌幅最大,2 月至 12 月的回报率分别为-36.4%、-31.3%和-28.9%。
图 1:一月晴雨表正确预测全年表现的实例
这是我如何制作图 1 的:
sp3 = sp2[sp2['jan_sign'] == sp2['FebDec_sign']][['spreturn','FebDecreturn']]
width = 0.75 # the width of the barsfig, ax = plt.subplots(figsize=(40,20))
rects1 = ax.bar(sp3.index - width/2, sp3['spreturn'], width, label='Jan Return')
rects2 = ax.bar(sp3.index + width/2, sp3['FebDecreturn'], width, label='Feb-Dec Return')ax.set_ylabel('Return', fontsize=40)
ax.set_xlabel('Year', fontsize=40)
ax.set_title("Jan Barometer on SP500",fontsize=40)
ax.legend(fontsize=40)
ax.tick_params(axis='both', which='major', labelsize=40)
下面的图 2 显示了一月份气压计失灵的 57 次。当跟随指标时,投资者可能会错过大的市场收益。例如,明智的做法是不要在 1927 年和 2009 年遵循这一理论,当时晴雨表预测今年为负,但当年剩余时间的回报率实际上为正,分别为 30.3%和 28.3%。另一方面,晴雨表也可能有风险,它预测一个积极的一年,但最终却是消极的一年。例如,在 1931 年,1 月份的回报率为正 3.1%,但当年剩余时间的收益率大幅下跌-47.1%。
图 2:一月份的晴雨表错误预测全年表现的实例
气压计在其他指标上的表现
我使用雅虎财经的纳斯达克综合指数、道琼斯指数和罗素 2000 指数的每日收盘价数据,应用晴雨表来观察它的表现。在图 3 中,如果忽略晴雨表,总回报代表在数据中所有年份都保持投资的年化回报。如果投资者仅在 1 月份回报率为正的年份投资(假设 1 月份没有投资),则晴雨表回报率是年化回报率。有趣的是,通过遵循一月晴雨表理论,投资者将获得比忽视该指标更大的回报。每个指数的成功率都比抛硬币要好,其中纳斯达克综合指数的成功率最高(67%)。无论 30 种证券或 500 种证券或大型技术公司或小型公司的指数,1 月份的晴雨表表现良好。
图 3
图 4
气压计在行业层面的表现
利用雅虎财经 21 年的 S&P500 板块数据,我发现了每个板块的晴雨表强度。该理论在医疗保健和公用事业领域的效果最好,成功率分别为 67%和 62%。金融部门表现最差,只有 38%的成功率。
图 4
下面的代码是我如何制作组合条形图和折线图的,它清楚地显示了正确预测的年份和成功率之间的趋势和关系:
fig, ax1 = plt.subplots(figsize=(15, 5))
plt.style.use('seaborn-white')
ax2 = ax1.twinx()
chart = df_sector.set_index('Sector')['Correctly Predicted Years'].plot(kind='bar',color = 'y', ax=ax1)
df_sector.set_index('Sector')['sucess_rate'].plot(kind='line', marker='d', ax=ax2)ax1.set_ylabel("Correctly Predicted # of Years",fontsize=14)
ax2.set_ylabel("Success rate",fontsize=14)
ax1.set_ylim([0,16])
chart.set_xticklabels(chart.get_xticklabels(), rotation=45,fontsize=16)
ax2.legend(loc=9, bbox_to_anchor=(1, -0.2),fontsize=14)
ax1.legend(loc=9, bbox_to_anchor=(1, -0.3),fontsize=14)
plt.title("Jan Barometer Success Rate by Sectors", y=1.02, fontsize=20)
plt.tick_params(axis='both', which='major', labelsize=12)
ax1.tick_params(axis='both', which='major', labelsize=12)
图 5
如果忽略该指标,并投资所有 21 年,非必需消费品行业的年化回报率最高(6.6%)。非必需消费品板块是唯一一个在忽略晴雨表(6.6%)时表现好于遵循理论(6.1%)的板块。当投资于晴雨表预测为正年的年份时,所有其他行业都有较高的回报。公用事业部门的平均回报率最高,为 10.1%,而金融行业的平均回报率最低,为-1.8%。
图 6
图 7
从统计学的角度来说,混淆矩阵是显示预测模型错误的一种直观方式。我计算了四个指标:真阳性、假阳性、假阴性和真阴性。真正的积极是当气压计正确预测一个积极的一年。假阳性是指气压计错误地预测了一个正年份,导致投资者亏损。假负是指一月份的回报为负,但一年中的其他时间回报为正,因此投资者错过了一项有利可图的投资。真正的负值是当晴雨表正确地预测到一个不利的年份,帮助投资者避免一个糟糕的投资。真正的积极和真正的消极衡量一月晴雨表理论的成功。假阳性和假阴性衡量指标的误差。材料行业的假阴性案例最多,投资者错过了好的投资机会。当投资者在投资组合中失去收益时,金融类股的误判率最高。
图 8
一月气压计和过去的流行病
随着当前 COVID 19 疫情的爆发,我很想看看 1 月份关于以往流行病和大流行的晴雨表的表现。以 LiveScience.com 为参照,我选取了最近的 8 次疫情,发现标准普尔 500 1 月和 2 月至 12 月为疫情爆发的第一年。一月晴雨表对 8 次爆发中的 5 次有效,成功率为 62.5%。2020 年,1 月份的回报率为负(-0.99%),因此,如果遵循该指标,今年剩余时间的回报率也可能为负。2009 年,当猪流感出现时,1 月份的回报是负的,但与其他疫情相比,当年其余时间的回报是最高的。然而,这在很大程度上是由于央行非常规的量化宽松货币政策。这与今天美联储使用同样的货币工具的情况相当。尽管晴雨表预测,随着美联储在 2020 年的干预,市场可能会经历一场繁荣。
图九
图 10
总的来说,一月晴雨表确实有效,跟踪它,回报比忽略它要高。然而,投资者应谨慎使用,因为许多其他因素,如美联储的货币政策和地缘政治因素也会影响市场。
Git Hub Repo:
https://github . com/joohirana/mediu article _ januarybarometer 2020 . git
参考:
纵观历史,疾病爆发蹂躏人类,有时会改变历史进程…
www.livescience.com](https://www.livescience.com/worst-epidemics-and-pandemics-in-history.html)
[1] O. Jarus,历史上 20 次最严重的流行病和大流行(2020 年),《生活科学》。
Python 函数-工具技巧!
一个简单的方法来提升你的代码,使它更干净,更实用,有时甚至更快!
图片来自这里
在这篇文章中,我将展示 Python 标准库 Functools 模块的一些最佳用法。
Functools (Function-tools)能为我们做什么?
STL 库的 functools 有很好的特性,允许我们用很少的代码甚至不用代码就能修改自己的函数,并给它们添加功能。
所有这些都会产生更清晰、更有效的代码,易于理解、监控和审查。所以,事不宜迟,让我们开始吧!
减少
Reduce 采用一个包含两个参数和一个 iterable 的函数,并在整个 iterable 上累积执行操作!
例如,如果我们用一个函数来增加数字,使用 reduce,我们就可以累加我们想要的每一个列表!或者串连字符串!
这里有一个例子:
这在想要在一列项目上实现的自定义函数中会派上用场,如果它是唯一的乘法,或者特殊的对象操作!
部分功能
部分函数是第二个函数,在许多参数中有用户固定的值。这使我们能够使用和创建简单方便的功能,而无需重写原来的功能!
一如既往——代码胜于文字。
缓存属性
我把这个放在最后,主要有两个原因:首先,它是 python 3.8 中的新特性,并不是每个人都已经更新了。第二个原因是它有更多的高级用途,主要是在大数据应用中。
我们都知道类属性的用法;它们是在访问时计算的,通常与对象的其他参数一起计算。
有时您只需计算一次,因此从 Python 3.8 开始,您可以通过缓存这些值来节省大量计算时间,而不必每次访问属性时都重新计算它们,如下所示:
最后的想法
Python 标准库有很棒的工具供您使用。functools 模块有很好的方法让你的代码更干净,更简单,有时甚至更快!
如果您对此感兴趣,请发表评论,我将写更多关于 Python 标准库特性的文章,这些特性没有足够多的人知道。
希望你喜欢这个!
成为真正程序员的 Python 基础,第 1 部分
您必须知道的事情-提高您的 Python 技能
图像来源
Python 路径
Python 有这种魅力。人们近乎浪漫地谈论它,说它是“简单的英语”。它是如此“简单易懂”,以及引入开源社区奇妙模块的力量——一切尽在掌握之中。
嗯,难道不是吗?
这是毫无疑问的,但我的朋友是第一级。
第一级是每个 python 开发者成为真正的 python 开发者的必经之路,我希望在这篇文章结束时,带你进入更高级的层次,并向你展示你必须走的路。
“知道特征并不能让一个人成为专家,理解特征才能做到.”
起初
这篇文章将随着时间的推移而进步,但是我想从更好地理解类开始。
类被认为是一个对象的蓝图,init 创建这个对象,或者说构造它(很多构建的类比参与进来)。
这个定义是公平的,但是它遗漏了 python 类的一个重要方面。
这个物体是什么?
您创建的这个对象可能会有属性和自我操作,但是 python 通过“dunder 方法”给了您更多
基础知识
让我们从简单的事情开始——假设我们需要一个类来表示一个多项式,它可能看起来像这样:
我们希望能够将它们相加或相减,甚至以简单适当的方式将它们打印到屏幕上,这里有三个最基本的“dunder 方法”,您可以添加适当的方法,并且可以使用这些操作!
如果这看起来是因为 zip 函数而完成的,不用担心,zip 只是将两个可重复项捆绑成一个可重复项的方法。
对我们来说最重要的是理解语法并不重要,你认识到数据模型函数(“dunder 方法”)允许你操作对象本身。
这是我在这里提出的至关重要的概念,它开始很简单,但会变得越来越有趣。
第三级——世界是一个对象
这句话是俗语,从 python 3 开始,一切都是对象,但这句流行语是什么意思呢?
乔恩·泰森在 Unsplash 上的照片
这里有一个典型的例子来说明它的意义。假设我们想测量一个函数运行的时间。
现在我解决了一个局部问题,如果我想把它加到 20 个函数上呢?这种方式是错误的,它没有考虑到 python 中的一切都是对象,包括函数 sub。
我可以调用子函数并修改它,调用的子函数会在函数上添加一个时间检查。
第 5 步——核心概念,第 7 步,是以语法的方式。
第 5 步和第 7 步没有区别。是一样的;这个 **叫做装饰器,**装饰器让程序员 在自己的函数中添加 功能性 , 而不触及核心函数本身。
更多关于“args”、“kwargs”的数据,请点击此处:
一个小小的语法变化,是你编码技能的一大步
medium.com](https://medium.com/swlh/change-the-way-you-write-python-code-with-one-extra-character-6665b73803c1)
不要急于求成!
同时这也暗示了第 2 篇文章(目前是最后一篇)的开始概念。
下一篇文章将更深入地挖掘这种语言的核心和特性,并希望让您更好地理解 python 是什么,而不仅仅是一些花哨的导入和看起来像这样的东西:
我希望您喜欢这篇文章,我知道我喜欢,我想把所有东西都挤在一篇文章中,但它感觉太紧凑了,我希望在下一篇文章中看到您,我也希望这篇文章给您带来一些新的东西!
在这篇文章的第二部分之前,请阅读以下内容:
Python collections 是一个被低估的库,它可以将您的编码提升到下一个级别。
medium.com](https://medium.com/swlh/python-collections-you-should-always-be-using-b579b9e59e4)
感谢阅读!
Python 生成器
使用 yield 关键字开发 python 生成器函数的教程
图片来自皮克斯拜
简单地说,Python 生成器促进了维护持久状态的功能。这使得增量计算和迭代成为可能。此外,生成器可以用来代替数组以节省内存。这是因为生成器不存储值,而是存储带有函数状态的计算逻辑,类似于一个准备启动的未赋值函数实例。
生成器表达式
生成器表达式可以用来代替数组创建操作。与数组不同,生成器将在运行时生成数字。
>>> import sys
>>> a = [x for x in range(1000000)]
>>> b = (x for x in range(1000000))
>>> sys.getsizeof(a)
8697472
>>> sys.getsizeof(b)
128
>>> a
[0, 1, ... 999999]
>>> b
<generator object <genexpr> at 0x1020de6d0>
我们可以看到,在上面的场景中,通过用生成器代替数组,我们节省了大量内存。
用收益代替回报的函数
让我们考虑一个简单的例子,你想产生任意数量的素数。下面是检查一个数是否是质数的函数,以及将产生无穷多个质数的生成器。
def isPrime(n):
if n < 2 or n % 1 > 0:
return False
elif n == 2 or n == 3:
return True
for x in range(2, int(n**0.5) + 1):
if n % x == 0:
return False
return Truedef getPrimes():
value = 0
while True:
if isPrime(value):
yield value
value += 1
正如你在第二个函数中看到的,我们在一个 while 循环中迭代并产生质数。让我们看看如何使用上面的生成器。
primes = getPrimes()>>> next(primes)
2
>>> next(primes)
3
>>> next(primes)
5
首先,我们调用函数并获取生成器实例。虽然这可以模拟一个无限数组,但是还没有找到任何元素。如果你调用list(primes)
,你的程序可能会因为内存错误而崩溃。然而,对于质数,它不会到达那里,因为质数空间对于在有限时间内达到内存限制的计算是稀疏的。但是,对于发电机,你不会事先知道长度。如果您调用len(primes)
,您将得到下面的错误,原因与数字只在运行时生成的原因完全相同。
----------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-a6773446b45c> in <module>
----> 1 len(primes)
TypeError: object of type 'generator' has no len()
迭代次数有限的生成器
虽然我们的质数例子有一个无限的迭代空间,但在大多数日常场景中,我们面对的是有限的计算。因此,让我们来看一个例子,我们可以用它来读取一个包含文本数据和下一行句子的语义分数的文件。
为什么我们需要使用收益率?
假设文件是 1TB,词的语料库是 500000。它不适合存储。一个简单的解决方案是一次读取两行,计算每行的单词字典,并在下一行返回语义得分。该文件如下所示。
The product is well packed
5
Edges of the packaging was damaged and print was faded.
3
Avoid this product. Never going to buy anything from ShopX.
1
Shipping took a very long time
2
很明显,我们不需要马上打开文件。此外,这些线条必须矢量化,并可能保存到另一个可以直接解析的文件中,以训练机器学习模型。因此,给我们一个干净代码的选项是使用一个生成器,它可以一次读取两行,并以元组的形式给我们数据和语义得分。
实现文件解析生成器
假设我们在一个名为test.txt
的文件中有上述文本文档。我们将使用下面的生成器函数来读取文件。
def readData(path):
with open(path) as f:
sentiment = ""
line = ""
for n, d in enumerate(f):
if n % 2 == 0:
line = d.strip()
else:
sentiment = int(d.strip())
yield line, sentiment
我们可以在一个for
循环中使用上述函数,如下所示。
>>> data = readData("test.txt")
>>> for l, s in data: print(l, s)
The product is well packed 5
Edges of the packaging was damaged and print was faded. 3
Avoid this product. Never going to buy anything from ShopX. 1
Shipping took a very long time 2
发电机如何退出?
在一个普通的 for 循环中,当生成器不再生成时,迭代停止。然而,这可以通过我们在生成器实例上手动调用next()
来观察到。超出迭代限制调用next()
将引发以下异常。
----------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-41-cddec6aa1599> in <module>
---> 28 print(next(data))StopIteration:
使用发送、抛出和关闭
发送功能
让我们回忆一下质数的例子。假设我们想将我们的生成函数的值重置为 100,如果它们是质数,就开始产生大于 100 的值。我们可以在生成器实例上使用send()
方法将一个值推入生成器,如下所示。
>>> primes = getPrimes()
>>> next(primes)
2
>>> primes.send(10)
11
>>> primes.send(100)
101
注意,在调用send()
之前,我们必须至少调用next()
一次。让我们看看我们必须如何修改我们的函数来适应这个目的。因为该函数应该知道如何分配接收到的值。
def getPrimes():
value = 0
while True:
if isPrime(value):
i = yield value
if i is not None:
value = i
value += 1
我们将产生的值存储在变量i
中。如果那不是None
类型,我们把它赋给value
变量。None
检查至关重要,因为第一个next()
在value
变量中没有要产出的值。
投掷功能
假设您想要在大于 10 的值处结束迭代,以避免溢出或超时(假设)。throw()
功能可用于提示发电机暂停引发异常。
primes = getPrimes()for x in primes:
if x > 10:
primes.throw(ValueError, "Too large")
print(x)
这种技术对于验证输入很有用。逻辑取决于发生器的用户。这将产生以下输出。
2
3
5
7----------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-113-37adca265503> in <module>
**12** for x in primes:
**13** if x > 10:
---> 14 primes.throw(ValueError, "Too large")
**15** print(x)
<ipython-input-113-37adca265503> in getPrimes()
**3** while True:
**4** if isPrime(value):
----> 5 i = yield value
**6** if i is not None:
**7** value = i
ValueError: Too large
关闭功能
处理闭包时没有异常通常是优雅的。在这种情况下,close()
函数可以用来有效地关闭迭代器。
primes = getPrimes()for x in primes:
if x > 10:
primes.close()
print(x)
这将为我们提供以下输出。
2
3
5
7
11
请注意,我们的值是 11,这是最后一个大于 11 的计算值。这模拟了 C/C++中 do while 循环的行为。
我相信这篇文章将有助于你将来开发更好的软件和研究程序。感谢阅读。
干杯😃
Python:遗传算法和旅行推销员问题
当分类和回归…没用的时候怎么办!
信用:Pixabay
在过去的 5 年里,数据科学受到了疯狂的复仇者级别的炒作。但是你知道运筹学也同样有趣、有益和具有挑战性吗?然而,与数据科学不同的是, OR 并不是 100%专注于将分类和回归技术应用于任何和所有问题。
我说这话有点言不由衷。
不过是~真的。很少有任务不能被强制成分类或回归问题。但是今天让我们换个话题,讨论其中的一些问题。两个高度影响的问题包括“旅行推销员问题”和“车辆路径问题”后者要复杂得多,涉及到时间因素,而且常常涉及到几辆车。但是在这篇介绍性的文章中,让我们关注两者中更容易的一个。
什么是旅行推销员问题?(TSP)
考虑一个推销员,他离开任何给定的地点(我们说是芝加哥),在回家之前必须在其他 x 个城市停留。维基百科方便地列出了美国前十大城市,所以我们只关注前 25 个。
像任何可以优化的问题一样,必须有一个代价函数。在 TSP 的上下文中,必须尽可能地减少总行驶距离。一个强力的解决方案对于 25 个城市来说是 100%可能的,然而,它比你想象的要复杂的多。25 个城市有 15,511,210,043,330,985,984,000,000 种不同的排列。这大约是 15.5 亿英镑。你知道七月是一个词吗?
有了这么多可能的组合,找到全局最优解有点像在针堆里找一根干草。是的,你没看错。作为回应,我们的目标不是找到全局最优解——而是找到无数个近似最优解中的一个,并避免无数个中等好的(和绝对糟糕的)解。这是遗传算法的一大进步。
什么是遗传算法?
遗传算法是一类从遗传学中获取灵感的算法。更具体地说,“基因”通过交叉(繁殖)和突变经过多次迭代而进化。这可能有点乱伦,但请原谅我。在最简单的情况下,我们从两个基因开始,这些基因相互作用(交叉),产生一个新基因,从一个基因获得一些属性,从另一个基因获得其余属性。然后,随机变化(突变)被引入新基因。现在有三个基因,两个父母和一个孩子;所有这三个都根据成本函数进行评估。如果孩子是最弱的,我们删除它,重新开始。否则,我们去掉双亲中较弱的一个,然后用剩下的两个基因重复整个过程。从概念上讲,这就是全部。
它基本上是进行 x 猜测,创建 y 混合猜测,评估基因库的适应性并做一些修剪。冲洗并重复,直到你收敛于一个解决方案。(你会收敛到一个解,它很可能是全局最优解而不是。)是的,因为计算机正在从遗传学中汲取灵感,但并没有受到遗传学特性的内在限制,所以算法在每次迭代中可以有任意数量的父母和子女。
变异和交叉起什么作用?
早期,变异是王道。这是“探索-利用”范式中的探索(在强化学习术语中很常见。)突变学习什么“管用”。然而,随着系统开始学习什么是有效的,什么是无效的,重要的是改变方式,开始很好地利用我们的知识——通过交叉——并利用我们所学的知识。有几种方法可以做到这一点。它可以是突然的转变,也可以是逐渐的变化。但关键是以科学家的思维开始,从环境中学习,以商人的思维结束,从学到的经验中获利。
好吧,但这在实践中意味着什么?
在 TSP 的上下文中,每个“基因”将是一个城市序列,以芝加哥开始和结束。任何给定基因的“适应度”是其往返总距离。我们从随机产生的 x 基因开始。如果我们只是偶然发现了全局最优解,那将是不可思议的,但这是不可能的;同样,任何起始基因都不太可能是字面上最糟糕的旅行。但是,有些基因会比其他基因更“适合”。注意我们只随机生成基因一次。 过了这一点,每一个新的基因都是交叉和突变的函数。在 TSP 的上下文中,这意味着随机地从先前的基因中继承城市和它们各自的索引。例如,我们可能从一个父母基因中继承“达拉斯”作为第五个元素,从另一个父母基因中继承“纳什维尔”作为第六个元素。请注意,我们随机选择了这些城市及其指数;我们不知道这是否有益。我们只是简单地去做,然后抱最大的希望。如果这不是有利的,新的基因被丢弃,我们重新开始。但是如果这个随机选择 是 有益的,我们就丢弃较弱的亲代基因并继续。我们仍然不知道达拉斯获得第五个指数是否有什么神奇之处,但在当时它似乎是有利的,所以最新的基因进化来保持它。
这个过程一遍又一遍地重复。
最终,一个基因将会“非常好”,并且在随后的迭代中不会被替换。我们的基因将很有可能陷入局部最优。但这是可以接受的,因为有超过 1570 亿种选择,而绝大多数都非常糟糕。但这是普遍生活的真实情况。种类繁多,谁说老虎进化对而狮子进化错了?当然,一只古代通灵串联战象会胜过这两者(谷歌一下),但是这种可能性还没有在我们的物理宇宙中实现,而且(可悲的是)它可能永远不会实现。
现在是代码!
一对夫妇注意,(A)我已经包括了一个小功能,将查询谷歌地图之间的距离位置。(B)我从这里得到了排名前 25 的城市,以及©我是否使用了作为迭代函数逐渐减少的ε参数,有利于早期探索和后期开发。
现在让我们来看看结果。我们开始时总持续时间超过 25,000 英里,后来减少到大约 10,000 英里。(对于一个运行了~3 秒的算法来说,已经不错了!)
如你所见,我们和被卷入了我几乎可以肯定是局部最优的情况,但是公路旅行实际上是有意义的,这真的很酷!您需要对这段代码进行大量的修改,以适应不同的目的,但是市场上有更健壮的遗传算法实现。我只希望这篇文章扩展了您对分类和回归世界之外的可能性的认识。
感谢阅读!如果你认为我的内容没问题,请订阅:)
Python 图形用户界面应用
Tkinter 图书馆的近距离观察
当今应用程序最重要的部分之一是图形用户界面本身。
这是因为市场竞争激烈,已经饱和,甚至不再关注功能,而是谁能让它看起来更漂亮,使用起来更简单。
今天我们将学习如何用最流行的编程语言之一 Python 创建和构建 GUI 应用程序。
这个简短的教程将会逐行解释,并且非常容易理解,尽管你可能没有太多 Python 或编程的经验。
环境
对于这个应用程序的开发,你不会需要太多,如果你已经熟悉 Python,你可以跳到本文的下一章。
代码和软件开发我个人选择的是 Visual Studio 代码 。
接下来,我们需要安装 Python,所以如果你使用的是 Ubuntu 或类似的 Linux 发行版,Python 是预装的。
如果不是这样,您可以像这样安装它:
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install python3.8
*在撰写本文时,Python 3.8 是最新的稳定版本,建议 PPA 使用 deadsnakes。
在其他操作系统上,如 windows 或 mac ,您将通过下载可执行安装并运行它来安装它。
Tkinter 库
我们还必须安装用于开发的 Tkinter 库:
sudo apt-get install python3-tk
[tkinter](https://docs.python.org/3/library/tkinter.html#module-tkinter)
包(“Tk 接口”)是 Tk GUI 工具包的标准 Python 接口。
编码
在我们开始导入所需库的编码时:
import tkinter
一旦我们导入了它们,我们就能够在我们的代码中使用它们,通常,您的代码编辑器将能够从那些库中识别出关键字,并尽可能地使您的输入更容易。
接下来是创建窗口,我们将使用它来添加元素并作为 GUI 应用程序的主窗口。
window = tkinter.Tk()
Tk 的顶层小部件,主要代表应用程序的主窗口。它有一个相关的 Tcl 解释器。
初始化窗口后,你所要做的就是调用 Tk 的主循环,它将执行你为 GUI 设置的所有命令。
window.mainloop()
主循环负责任何事件,比如按钮点击或者文本框输入,从运行到窗口关闭。
使用以下命令运行 Python 文件:
python3 GUI.py
这里是我们的第一个窗口!
这只是我们应用程序的开始,我们接下来要做的是定制我们的窗口!
标题
向我们的窗口添加标题非常简单:
window.title("Python GUI")
“Python GUI”主窗口
这里需要注意的一件重要事情是,我们希望为我们的窗口执行的每一条 命令 都必须在“window.mainloop()”之前,因为否则它不会显示在 GUI 中。
窗口大小
设置一个特定的窗口大小是相当重要的,因为你可能需要更多的空间来放置我们稍后将要添加的元素!
方法是:
window.geometry("450x250")
第一部分是宽度,后面是分隔为“x”和高度的数字。
设置完基本的窗口设置后,我们就可以向 GUI 应用程序添加元素了。
元素
这里我们可以使用不同种类的元素,它们是由 Tkinter 库提供给我们的,但是我们将把重点放在对每个 GUI 应用程序最重要的四个元素上。
分别是:标签、按钮、条目(输入)、和文本
标签
在每一个 GUI 中,为使用程序的用户创建某种文本显示是很重要的。
label = tkinter.Label(window, text="Some label text",width = 50)
我们将标签保存在名为“变量”的变量下,并将其定义为属于我们的主“窗口”,包含一些文本,并且可以定义额外的参数,如宽度等。
定义标签后的一个重要步骤是,我们必须将它打包并设置到窗口中。有一个名为 pack()的函数正好可以做到这一点:
label.pack()
该几何管理器在将微件放入父微件之前,将微件组织成块。
纽扣
我们使用按钮来执行某种类型的命令或我们的应用程序可能需要的后端功能。
因为我们需要某种功能,所以我们定义‘clicked’来在每次按钮被点击时创建一个新标签。
def clicked():
label = tkinter.Label(window, text="Button label",width = 50)
label.pack()butt = tkinter.Button(window, text="Click button!", command=clicked,width = 10)butt.pack()
每次点击按钮,都会创建一个带有类型标签的新对象,显示在前一个对象的下方。
条目(文本框)
这个元素在 Tkinkter 库中被称为条目,但对于许多其他编程语言来说,它在术语文本框下也很常见。
让我们看看如何实现它:
entry = tkinter.Entry(window, width=10)entry.pack()
Entry 元素的有用功能是我们可以检索用户在里面写了什么,但是在二进制转换器的例子中有更多的内容。
文本
专门的文本框,比常规条目更具可定制性。
我们是这样使用它的:
text = tkinter.Text(window, width=20, height=5)text.insert(tkinter.INSERT, "Hello")text.insert(tkinter.END, "World")text.pack()
我们有像 INSERT 和 END 这样的参数,所以我们可以指定我们想要的文本的位置。欲了解更多信息,请点击这里。
一旦我们完成了所有必要的元素,让我们用刚刚学到的知识来构建一个实际的应用程序。
从头开始构建我们自己的应用程序
我们应该创造一些对我们有意义和有用的东西。
我的第一个想法是简单的计算器,这样我们可以利用我们在教程中谈到的所有元素。
让我们来看看我在这里写的完整代码:
我们基本上使用了我们讨论过的所有元素,我在 add 和 sub 函数中创建了简单的文本和条目操作。
每次单击添加两个数字时,文本元素都会被清除,并插入新值。
还有 ValueError 处理,它将捕捉除数字之外的任何内容,这很好。
以下是教程和计算器示例的完整代码。
在 GitHub 上创建一个帐户,为 lazargugleta/Python-Gui 开发做出贡献。
github.com](https://github.com/lazargugleta/Python-Gui)
今天就到这里吧,我美丽的人们。
结论和后续步骤
这只是一个非常简单的 Python 图形用户界面,在我看来,如果每个人都跟着做,他们就能做到!
虽然简单,但它是一个非常强大的软件,可以用来创建现实世界的应用程序!
保持创意,关注我以获得更多像这样的教程!
Python:从头开始的哈密顿蒙特卡罗
物理学和统计学即将发生碰撞,这并不像你想象的那么可怕
信用:Pixabay
如果你对马尔可夫链蒙特卡罗(MCMC)方法的体验和我一样,那就是无止境的寻找答案。每当你得到一个问题的答案,就会有十几个问题冒出来!你不断地学习你不知道的东西。我最近接受了一份全职工作,在一个组织担任数据科学家,该组织广泛使用贝叶斯统计,并通过扩展使用 MCMC 方法。所以我决定和这个数学分支一战到底!关于 Metropolis,Metropolis-Hastings,和哈密顿蒙特卡罗的详细回顾,请访问我的公共 Google Colab 笔记本😃
在深入研究新材料之前,我将重温 Metropolis-Hastings (MH)背后的关键思想,因为哈密顿蒙特卡罗(HMC)是 MH 的扩展。
大都会黑斯廷斯
大都会-黑斯廷斯是一个美化的随机漫步。你需要四个要素:一个起点,一个目标分布,一个提案分布,一个公正的评委(随机事件。)目标分布可以是您想要从中取样的任何分布;你需要的只是概率密度函数(PDF)。同样,建议分布可以是任何 PDF(尽管如果分布是对称的,数学会更简单。)整个想法是从使用建议分布的随机点开始。将其追加到数组中。将这一点输入目标的 PDF 以获得概率密度(也称为可能性)。现在,通过建议分布生成一个扰动,将它添加到当前位置,为这个变量指定一个新名称,并通过目标的 PDF 评估它的可能性。比较可能性
acceptance = target_PDF(proposed)/target_PDF(current)
这个数字将落在[0,inf 范围内的任何地方。如果小于 1,你有 x%的机会移动。任何高于 1 的都是保证运动。这就是“公正的法官”的用武之地。观察一个随机事件(通常是从均匀分布中抽取的[0,1]中的一个数。)如果这个数字小于或等于接受度,您就移动到建议点。否则,你留在原来的位置。将获胜者追加到数组中。这就是大都会算法。
如果提案分布不对称,事情会稍微复杂一些*。如果你从正态分布、均匀分布等中抽取运动样本,这一步是不必要的。但是,如果使用分布,如伽玛、泊松、指数、对数正态等。那么你需要考虑固有的偏见。在我在开头链接的 Colab 笔记本中,我使用了一个β建议分布,带有一个(-0.5 常数项),偏向 1(与对称或偏向 0 相反。)需要注意两件事:首先,Beta 分布被定义为[0,1]意味着我们将永远不会观察到负扰动,这意味着我们的建议将越来越多地只向一个方向移动。我增加了-0.5 的偏置,这样正负样本就可以对扰动进行采样。第二个,不过,分布还是偏向 1,也就是说它只会在一个方向慢慢蠕动。我们需要对此做出解释。我们通过获得扰动和反向*扰动的可能性来做到这一点。**
def correct(prop,curr,a=3,b=2):
x0 = curr - prop + 0.5
x1 = prop - curr + 0.5
b0 = beta.pdf(x=x0, a=a, b=b)
b1 = beta.pdf(x=x1, a=a, b=b)
return b0/b1
这个修正项(你将在 Colab 笔记本中看到)乘以似然比;它解释了提议分布的不对称性。(注意,这个比率被称为黑斯廷斯比率,因为它是 Metropolis 和 MH 算法之间的唯一区别。)
您可以使用 MH 算法从大多数分布中进行采样。然而,在一天结束时,它基本上是一次随机漫步。没有逻辑告诉我们在当前位置应该有多大的跳跃。当对 1 变量分布进行采样时,这不是问题。但是随着维度的增加,高可能性区域仅构成总面积的一小部分,而中等和低可能性区域构成(指数地)总面积的更多部分。当对低维分布进行采样时,这种效应对 MH 仅造成轻微的低效。但是随着维数的增加,MH 冒着返回不代表目标分布的样本的风险。
原因是在峰值附近进行小幅度跳跃是合适的,因为相对于其可能性而言,过度勘探该区域的风险较低;然而,当我们向尾部移动时,相对于它们的可能性,对这些区域的过度勘探会成为一个相当大的风险。(从上下文来看,一条尾巴上有许多样本而另一条尾巴上没有样本是不可取的。)那么…我们如何在考虑可能性的情况下提出跳跃呢?
哈密顿蒙特卡罗
物理学有答案——万岁!在这篇文章的剩余部分,我们不会把地点看成是随机漫步。相反,我们将把分布的绝对峰值视为一个行星。一颗卫星将环绕这颗行星运行,收集样本。哈密顿力学使用微分方程将动能和势能联系起来。这些微分方程有非常棘手的精确解,但使用蛙跳积分友好的近似解。微分方程的积分将给出我们的卫星将遵循的路径。这些微分方程(或哈密顿方程)根据动能和势能定义了系统的能量。当你把球抛向空中时,它的动能被势能所代替。当球下落时,它的势能被动能所代替。哈密尔顿方程定义了位置和动量之间的关系:
T = time
Q = position
P = momentum
K = kinetic energy
V = potential energydQ/dT = P
dP/dT = dV/dQ
请注意,上述等式是在统计学背景下推导出来的。物理世界必然要复杂得多。
值得注意的是,我们的微分方程是 dQ/dT,位置 wrt(相对于)时间的变化,和 dP/dT,动量 wrt 时间的变化,其评估为势能 wrt 位置的变化。我们可以根据 PDF 本身来定义位置。因此,动量的变化是 PDF 中位置*的函数,也就是离峰值的距离。请注意,正态分布的梯度分别在峰值和尾部之间的拐点处最陡。相反,负对数正态分布的梯度在尾部最陡,接近峰值时接近(并达到)0。正如我们之前讨论的:我们希望我们的跳跃大小 ro 与分布中的位置成比例。在接近顶峰时,我们想进行小幅度的跳跃。当我们接近尾部时,我们希望跳跃越来越大。事实证明,负对数正态分布梯度完美地实现了这一效果。(而正态分布梯度会从峰值 和尾部 提出小的跳跃,这是我们不想要的!)*
分布与梯度
该算法
该算法分为四个部分:
- 设置:取前一个位置复制,这样你就有了 q0 和 q1。从 N(0,1)中随机采样一个动量,然后复制,这样你就有了 p0 和 p1。对于单变量高斯,求 PDF 相对于位置
-(x-mu)/sigma^2
的梯度。 - 蛙跳:使用蛙跳积分更新 q1 和 p1(即哈密顿运动或一个质点。)实际上,这是最敏感的部分;小的调整会导致不稳定的行为。
- MH Dance :最后,将 p1 乘以(-1),这保证了可逆性(即给定动量 p0 可以从 q0 到达 q1,给定动量-p1 可以从 q1 到达 q0)。这给了我们大都会-黑斯廷斯“舞蹈”所需要的信息。请记住,我们使用的是负对数概率,所以数学就是加法和减法。然后接受/拒绝移动。
- 重复固定次数的迭代。
你可能已经注意到,在第一步中,我们从一个高斯样本中抽取动量。这是怎么回事?使用我们之前的卫星比喻,哈密顿运动将引导我们围绕特定可能性的轨道路径(访问与相同可能性相关的位置)。)然而,我们对探索一种可能性不感兴趣,我们想探索所有的可能性。为了实现这种效果,我们对动量“踢”进行采样,这可能导致我们的卫星跳跃或坠落轨道距离(也称为访问不同的可能性。)
代码
再来看看性能!
N(0,1) HMC 采样器输出
扩展ˌ扩张
如果你想运行我的代码,请从头跳到 Google Colab 链接。您只有查看权限,没有编辑权限——但是您可以复制到您自己的 Google Drive 进行实验,下载 iPython 笔记本文件,等等。如果您仔细研究代码,您会注意到路径长度和步长是非常敏感的超参数。最轻微的调整可能会导致无意义的样本。这是基于梯度的 MCMC 采样器的诅咒。然而,还有希望——更新的方法,如无 U 形转弯采样器(NUTS ),通过动态选择路径长度和步长来构建 HMC。
但是为什么这是一个问题呢?从我们假设的卫星轨道示例来看,哈密尔顿方程将指导卫星的运动,“围绕”特定的可能性,这意味着它提出了类似可能性附近的新位置。但是围绕任何给定可能性的轨道长度是不同的。在较高的可能性下,圆周很小,但是当环绕较低的可能性(更接近尾部)时,圆周更大。)我们可以通过简单地观察高斯分布来直观地证实这一点。当 me 围绕给定的可能性做 360°轨道运动时会发生什么?我们提出我们目前的相同观点。在 HMC 的行话中,这被称为“U 型转弯”,意思是我们回到我们刚刚去过的地方。对路径长度和步长的动态调整控制了整合的程度(轨道路径。)如果你稍微摆弄一下代码,你就会发现,这些超参数非常敏感——因此在实践中你很可能会使用螺母而不是 HMC。
我必须给它应得的荣誉。谷歌的软件工程师科林·卡罗尔写了一个更具伸缩性的 HMC 实现。(我的只能用来采样一元高斯。)可扩展性是有代价的——可解释性。我发现要真正“理解”这个概念,我必须把它变得愚笨,然后从头开始构建一个。希望你喜欢这本书!
感谢您的阅读——如果您认为我的内容没问题,请订阅!😃
Python 有一个内置的数据库——下面是如何使用它
如何利用内置数据库进行数据存储和操作
数据库是存储数据的一种伟大、安全和可靠的方式。所有主要的关系数据库都有一个共同点——SQL——一种操作数据库、表和数据的语言。SQL 是一个涉及面很广的话题,尤其是在与不同的数据库供应商打交道时,比如 Microsoft、IBM 或 Oracle,所以让我们从 SQLite 开始,它是最轻量级的数据库系统。
克里斯蒂娜@ wocintechchat.com 在 Unsplash 上的照片
那么,SQLite 是什么?很高兴你问了这个问题。它是一个为我们提供数据库或关系数据库管理系统的库。术语“Lite”的意思是“轻量级”,这意味着它对于数据库领域的设置和管理来说是轻量级的。
我为什么要关心?因为你不需要下载软件或创建云数据库,然后弄清楚如何与 Python 连接,就可以获得数据库体验。当然,这不是最安全的选择,但它仍然远远胜过 CSV 和 Excel 文件,因为每个人都不能更改数据。
今天的文章结构如下:
- 问题概述
- 创建表格
- 创建、读取、更新、删除
- 测试时间
- 结论
因此,我们将介绍一些基础知识——如何创建表、插入数据、更新数据、删除数据、获取所有数据以及根据条件获取数据。它是构建应用程序所需的一切。
问题概述
你喜欢电影吗?是啊,我也是。今天,我们将通过创建一个数据库和一个表来存储电影标题和附加信息,来关注这一点。在我们制作好表格之后,我们需要声明几个函数:
- 要插入电影
- 获取所有电影
- 去买一部电影
- 若要更新单部电影
- 若要删除单部电影
听起来很多,其实不是。我们将使用 Python 与 SQLite 数据库通信,并且我们将从IMDB.com获取电影信息。
厉害!我们开始吧!
创建表格
我们不能直接在数据库中存储数据,我们需要表格。数据库存储表,表存储数据。我们的过程如下——仅当 movies 表不存在时才创建它。这将需要两个 SQL 查询,一个检查具有给定名称的表是否存在,另一个创建一个表。
首先,我们需要导入 SQLite 库,建立一个数据库连接,并创建一个游标。下面的代码片段可以做到这一点:
import sqlite3 conn = sqlite3.connect('movies.db')
c = conn.cursor()
如果 movies.db 数据库不存在,它将被创建,如果存在,只建立一个连接。
接下来,我们将声明一个函数来检查一个表是否存在。表名作为函数参数传递,如果表存在,则返回 True ,否则返回 False :
def table_exists(table_name):
c.execute('''SELECT count(name) FROM sqlite_master WHERE TYPE = 'table' AND name = '{}' '''.format(table_name))
if c.fetchone()[0] == 1:
return True
return False
新的 f-strings 由于某种原因不能工作,所以我们必须使用旧的语法——这不是问题,但是请记住这一点。下一步是使用声明的函数检查一个表是否存在,如果不存在就创建它。下面的代码片段可以做到这一点:
if not table_exists('movies'):
c.execute('''
CREATE TABLE movies(
movie_id INTEGER,
name TEXT,
release_year INTEGER,
genre TEXT,
rating REAL
)
''')
厉害!这部分到此结束,我们接下来将进入有趣的内容。
创建、读取、更新、删除
好了,我们已经配置好了一切,现在是处理数据的时候了。首先,我们需要一个向表中插入电影的函数(创建部分)。这很容易编写,因为我们需要执行一个 INSERT 语句并提交事务。代码如下:
def insert_movie(movie_id, name, release_year, genre, rating):
c.execute(''' INSERT INTO movies (movie_id, name, release_year, genre, rating) VALUES(?, ?, ?, ?, ?) ''', (movie_id, name, release_year, genre, rating))
conn.commit()
就是这样!我们将测试部分留到以后,现在我们将继续进行读取部分。
我们将在这里声明两个函数——第一个获取所有电影,第二个只获取一个电影,由电影 ID 指定。您可以轻松地将逻辑浓缩到一个函数中,但是我选择了这种方法。
下面是获取所有电影的函数:
def get_movies():
c.execute('''SELECT * FROM movies''')
data = []
for row in c.fetchall():
data.append(row)
return data
获取一部电影的代码片段:
def get_movie(movie_id):
c.execute('''SELECT * FROM movies WHERE movie_id = {}'''.format(movie_id))
data = []
for row in c.fetchall():
data.append(row)
return data
太好了!接下来是更新部分。这个比较棘手。我们希望根据给定的电影 ID 更新元素,但是我们将更新什么呢?我们是否为每个字段声明了一个特定的函数?听起来不太对劲。我们将使用字典来执行更新。
我来详细说明一下。我们的更新函数将接受两个参数:
- 电影 ID —您要更新的电影的 ID
- 更新字典—要更新的键/值对
更新字典中的键必须根据表列命名,否则会引发异常。此外,我们需要处理数字和文本字段的更新。这是迄今为止最棘手的函数,但是您可以处理它:
def update_movie(movie_id, update_dict):
valid_keys = ['name', 'release_year', 'genre', 'rating']
for key in update_dict.keys():
if key not in valid_keys:
raise Exception('Invalid field name!') for key in update_dict.keys():
if type(update_dict[key]) == str:
stmt = '''UPDATE movies SET {} = '{}' WHERE movie_id = {}'''.format(key, update_dict[key], movie_id)
else:
stmt = '''UPDATE movies SET {} = '{}' WHERE movie_id = {}'''.format(key, update_dict[key], movie_id) c.execute(stmt)
conn.commit()
看到了吗?没那么难。让我们完成删除部分。它比前一个简单得多,因为我们只需要执行一条语句并提交事务。代码如下:
def delete_movie(movie_id):
c.execute('''DELETE FROM movies WHERE movie_id = {}'''.format(movie_id))
conn.commit()
这部分到此结束。接下来我们将测试我们的函数。
测试时间
首先,让我们插入几部电影:
insert_movie(1, 'Titanic', 1997, 'Drama', 7.8)
insert_movie(2, 'The Day After Tomorrow', 2004, 'Action', 6.4)
insert_movie(3, '2012', 2009, 'Action', 5.8)
insert_movie(4, 'Men in Black', 1997, 'Action', 7.3)
insert_movie(5, 'World War Z', 2013, 'Romance', 10)
执行这五行代码不会像预期的那样向控制台输出任何内容——我们只是向表中插入数据。接下来,我们将使用预定义的函数来抓取所有电影:
print(get_movies())
厉害!现在让我们只看一部电影:
print(get_movie(2))
这很简单。现在我们来看看如何更新电影。最后一个插入的是世界大战 Z ,故意给了 10 分和一个爱情类型,所以让我们改变一下:
update_movie(5, {'genre': 'Horror', 'rating': 7.0})
现在事情说得通了。剩下要做的唯一一件事就是删除一部电影——让我们看看如何做:
delete_movie(3)
这不会像预期的那样返回任何内容。我们可以快速获取所有电影,看看删除功能是否有效:
这就做到了——一切都像广告宣传的那样。让我们在下一部分总结一下。
在你走之前
我希望这很容易理解。我们讨论了基础知识,留下了许多未触及的东西。构建基本的、数据库驱动的应用程序或 API 已经足够了,但是以后可以更多地使用 API。
请随意扩展它,添加新的函数或表,或者提高整体代码质量。
感谢阅读。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
原载于 2020 年 10 月 1 日 https://betterdatascience.com。
Python:如何获取实时市场数据(滞后小于 0.1 秒)。
这篇文章会有点特别。我将测试 Yahoo Finance API for Python 的最新版本,它提供了免费获取不到一秒钟延迟的实时数据的可能性。
在 Unsplash 上 ActionVance 拍照
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
在本文中,您将学习如何使用 Python 包获得实时股票市场数据,而无需调用昂贵的 API,如彭博。我已经帮你测试过了。那有用吗?让我们看看。
如果你现在热衷于自己动手,你可以在本文末尾找到完整的 Python 代码
您将能够使用 Python 包获得股票市场数据,如价格、交易量和基本面数据。(滞后小于 0.01 秒)
本文是下面文章的补充,在下面的文章中,我演示了如何用不到 3 行代码获得市场数据:
[## 如何从纽交所获取不到 3 行的市场数据(Python)。
在本文中,您将学习使用 Python 获取股票市场数据,如价格、交易量和基本面数据…
towardsdatascience.com](/how-to-get-market-data-from-the-nyse-in-less-than-3-lines-python-41791212709c)
好,我们开始吧。
开始前
首先,如果你想跟踪我的进度,在开始之前,你需要在你的机器上安装一个 Python 3 版本和以下软件包:
- 熊猫
- NumPy
- y 金融
- plottly(非强制,但对绘图有用)
如果这些软件包中的任何一个尚未安装,您可以使用 pip 命令,如下所示。
pip install yfinance
pip install plotly
一旦您确保安装了以下软件包,我们就可以开始了。
如果你已经有了使用 Python 的经验,可以跳到第二步。第一步是导入数据。
一、进口包装
第一步将包括导入必要的包。
首先,您将使用以下代码行导入先前安装的软件包:
上面几行是查询要导入的 numpy,pandas,yfinance & plotly。
一旦我们成立了,让我们进行下一步。
既然库已经导入,我们现在可以导入市场数据。
二。与市场接轨
既然已经上传了所需的不同包。我们将以 UBER 为例,通过 Yahoo Finance API 设置我们的导入。
Yahoo Finance API 将需要 3 个强制参数,顺序如下:
- 跑马灯 (1)
- 开始日期+结束日期或期间 (2)
- 音程 (3)
对于我们的例子,股票代号*(参数 1)* 将是 UBER 。此外,在本例中,我们将选择最后 5 天的时间段*(参数 2)* ,而不是定义开始和结束日期。我们将设置 5 分钟的间隔*(参数 3)* 。快速提醒一下,优步的股票代码是优步。
要调用您的数据,您必须使用以下结构:
上面描述了获取我们感兴趣的市场数据的结构。
在进一步讨论之前,我将带来第三个论点的一些细节(区间)。
区间快速查找
我想给你一个快速拍摄不同的间隔,你可以使用雅虎财经 API 设置。
下面详细列出了可能需要的间隔的完整列表:
上面列出了可以选择的不同间隔。
该间隔不会干扰获取实时数据的选项。
我们继续。
现场测试
当我执行下面的行时,我们是 2020 年 10 月 23 日,实际上是伦敦时间下午 5:13,这意味着市场是开放的。
仅供参考:英国时间下午 5:13 相当于纽约时间下午 1:13。
我们已经定义了 3 个参数,让我们执行下面的代码:
下面几行代码都是调用雅虎财经 API
简单回顾一下,下面的代码行调用 Yahoo finance API 并请求获得最近 5 天的数据,间隔为 5 分钟。
这里是的输出:
使用上面的代码发布的输出。
价格已经即时更新;我将数据与当前值进行了比较,我们匹配。
轰!
如您所见,每秒钟都有一个更新发布。例如,如果您查看下面的输出,所提供的最新数据是 1:13 PM 和 50 秒。如果您重新运行您的内核,数据将再次更新。
任务完成。
我把现场测试推得更远,你可以看到数据每秒都在更新,令人印象深刻。此外,您可以在下面的解释视频中获得完整的代码解释:
完整的现场测试编码和解释在上面的视频。
这是使用 Python 和 Plotly 传播的最终实时图:
最终输出:实时图表随时间更新。
赛义德·莱萨尼
如果你想在这个话题上更进一步,这里是本文的第二部分,有一个真实的算法交易例子:
我用 Python 实时测试了一个著名的预测市场的数学技术的实现…
medium.com](https://medium.com/analytics-vidhya/python-i-have-tested-a-trading-mathematical-technic-in-realtime-658a80381151)
来源:
(1)一天学会算法交易:
你好,我是赛义德·莱萨尼。我一直在伦敦的多家银行担任数据科学家,是一名…
www.udemy.com](https://www.udemy.com/course/python-for-algorithmic-trading/?couponCode=LOVE_SEPTEMBER)
完整的 python 代码:
完整的 Python 代码
2021 年的 Python 时间表和即将推出的功能
Gabriela Gomez 在 Unsplash 上拍摄的照片
Python 3.10 的一些新特性的预览
我们目前生活在 Python 3.8 的稳定时代,Python 的最新稳定版本 3.8.4 于上周发布。 Python 3.9 已经处于测试开发阶段,一个测试版 (3.9.0b4)于 2020 年 7 月 3 日预发布,第五个测试版预发布定于明天**。3.9 的第一个稳定版本预计在 2020 年 10 月发布。Python 3.10 的开发也于 2020 年 5 月启动,第一个测试版预计于 2021 年 5 月发布。**
显然,对于 Python 爱好者来说,有趣的时代就在前方。浏览三个版本(3.8、3.9 和 3.10)的发布时间表促使我在有趣的 Python 开发即将到来的时间表中编辑关键日期**。**
“我妈妈总是说生活就像一盒巧克力。你永远不知道你会得到什么。”——《阿甘正传》
Python 开发周期中的关键日期(未按比例)来源:https://www.python.org/dev/peps/
通常,在开发周期中会有 4–5 个测试版,在第一个测试版发布之后的版本中不会引入新的特性。对于 3.8,beta-1 于 2019 年 6 月发布,对于 3.9,beta-1 于 2020 年 5 月发布。虽然未来 Python 3.10** 刚刚启动,官方网站已经提供了一些的亮点。**
这篇文章旨在提供一个时间表的简要概述和一个即将到来的新 Python 版本的突出特性的预览,改编自 Python 网站的官方示例。请注意,我们可以期待在 3.10 版本中有更多的新功能,我会随时更新下面的列表。
突出 Python 3.10 中的功能
1)二进制表示中 1 的频率
将引入一个新方法bit_count()
,该方法将返回整数的二进制表示中存在的个一。结果将是独立于整数的符号。这个功能的一个用例是在信息论中,对于两个等长的字符串,您可以找到两个字符串不同的地方的总数。这种差异被称为汉明距离(参见 Wiki )。阅读这里的了解 Python 中这一功能的历史。****
这个方法简单地将str
类型的count
方法称为str.count('1')
。下面的例子解释了这一点
# Positive integer
>>> num = 108# Let's first get the binary representation of num
>>> bin(num)
'0b1101100'**>>>** num.bit_count()
4# Negative integer
>>> num = -108>>> bin(num)
'-0b1101100'**>>>** num.bit_count()
4# Under the hood
>>> bin(num).count('1')
2)拉链会“更严格”
一个新的可选关键字参数strict
将被添加到zip
函数中。如果你通过了strict=True
,你正在压缩的的长度必须相等,否则ValueError
将被抛出。在 Python 3.9 之前,如果您压缩两个长度不等的列表,您将得到长度等于较小列表的输出。
在下面的例子中可以看到,在 Python 3.10 之前,zip()
函数忽略了第一个列表中不匹配的'D'
。相比之下,Python 3.10 会抛出一个ValueError
。鉴于压缩相同数量的项目的直观性,我喜欢这个功能,因为它可以唤醒你重新检查你的输入。在 PEP 618 阅读更多关于这个问题的内容。
Python 3.10 之前
>>> list(zip(['A', 'B', 'C', 'D'], ['Apple', 'Ball', 'Cat']))
[('A', 'Apple'), ('B', 'Ball'), ('C', 'Cat')]
在 Python 3.10 中
>>> list(zip(['A', 'B', 'C', 'D'], ['Apple', 'Ball', 'Cat'],
strict=True))
Traceback (most recent call last):
*...*
ValueError: zip() argument 1 is longer than argument 2
3)字典的只读视图
字典的三个关键方法,keys()
、values()
和items()
,返回类似集合的对象,分别对应于字典的键、值和项的动态视图。您在这些视图中所做的任何更改也将反映到原始词典中。
在 Python 3.10 中,上述三种方法返回的所有视图都有一个名为mapping
的附加属性,该属性将返回映射的一个只读代理**。这个只读代理将包装视图引用的原始字典。下面的例子说明了这一点:**
让我们定义一个字典,并将它的键和值存储在不同的变量中
>>> fruits = {'Mangos': 12, 'Figs': 100, 'Guavas': 3, 'Kiwis': 70}
>>> keys = fruits.keys()
>>> values = fruits.values()>>> list(keys)
['Mangos', 'Figs', 'Guavas', 'Kiwis']
现在让我们使用del
语句从这个字典中删除两个元素。如果您现在打印键和值,您将看到它只返回剩余的项。原始字典中的变化现在反映在视图中(这里的keys
和values
)。
>>> del fruits['Figs']
>>> del fruits['Guavas']>>> print (list(keys), list(values))
['Mangos', 'Kiwis'] [12, 70]
现在,有了mapping
,你仍然可以得到原始字典的只读代理。酷!不是吗?
*# returns a read-only proxy of the* ***original dictionary***
>>> values.mapping
mappingproxy({'Mangos': 12, 'Figs': 100, 'Guavas': 3, 'Kiwis': 70})>>>values.mapping['Guavas']
3
4)移除一些向后兼容性
从 Python 3.10 起将取消对集合模块的抽象基类(ABCs)的别名支持。因此,现在是停止忽略相应的反对警告并调整代码的好时机。****
到 Python 3 . 9 . 0 B4(2020 年 7 月 3 日发布)
直接从collections
模块导入任何这些ABC 将导致到目前为止的DeprecationWarning
>>> from collections import ABC_NameDeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working
这让我想到了这篇文章的结尾。因为 Python 3.10 将会公布更多的发布亮点,所以我会将它们添加到本文中。敬请期待 让我们一起期待 Python 3.10 。你可以在这里关注当前版本和即将发布版本的发布时间表: 3.8 、 3.9 、 3.10 。如果您也想了解 Matplotlib 和 Scikit-learn 的最新特性,请阅读我最近发表的关于 Matplotlib 3 新特性和 Scikit-learn 新特性的文章。
用 Altair 实现 Python 交互式数据可视化
用不到 20 行代码创建交互式图表。
一个简单的例子
在我们进入细节之前,我想向您展示一个不到 20 行代码的交互式图表。
这个图表是用 Python 数据可视化库 Altair 创建的。Altair 是 Python 的一个声明性统计可视化库,基于 Vega 和 Vega-Lite 。Altair 提供了强大而简洁的可视化语法,使您能够快速构建各种各样的统计可视化。
这个库的关键思想是你在数据列和可视编码通道之间声明链接,比如 x 轴、y 轴、颜色等。其余的情节细节是自动处理的。基于这种声明性的绘图思想,可以使用相对简洁的语法创建一系列从简单到复杂的绘图和可视化。
下面是来自官方示例图库的部分示例截图。
来自官方示例图库的一些牛郎星示例
装置
这个库有很多依赖项,我强烈建议创建一个新的虚拟环境。此外,避免使用 base(root) 也是一个最佳实践,因为这可能会破坏您的系统。
关于创建 Python 虚拟环境的教程,你可以看看:
[## 使用“virtualenv”创建虚拟环境,并将其添加到 Jupyter 笔记本中
你是机器学习工程师,正在使用 Python 和 Jupyter Notebook 吗?在这篇文章中,你会看到为什么…
towardsdatascience.com](/create-virtual-environment-using-virtualenv-and-add-it-to-jupyter-notebook-6e1bf4e03415) [## 使用“conda”创建虚拟环境,并将其添加到 Jupyter 笔记本中
你正在使用 anaconda 和使用 Jupyter Notebook 和 Python 吗?在这篇文章中,你将看到如何创建虚拟的…
medium.com](https://medium.com/analytics-vidhya/create-virtual-environment-using-conda-and-add-it-to-jupyter-notebook-d319a81dfd1)
以下是安装 Altair 的两个选项:
- 终端— pip/conda
- 阿南康达-领航员
通过 pip/conda 的终端
假设您已经处于想要安装 Altair 的环境中。
Altair 可以与示例数据集一起安装在 vega_datasets 中,
pip install altair vega_datasets
如果您使用的是 conda 软件包管理器,则等同于:
conda install -c conda-forge altair vega_datasets
成功安装后,您应该能够打开 Jupyter Notebook 或 JupyterLab,并执行来自示例库的任何代码。
巨蟒领航员
启动anaconda-Navigator,导航到 环境 ,选择您喜欢安装 Altair 的环境,例如“数据可视化”。然后从下拉菜单中选择未安装。
重要提示:您应该始终避免使用 base(root) ,因为库及其依赖项的更新可能会破坏您的系统。
使用 Anaconda-Navigator 安装 Altair
从搜索字段中搜索牛郎星,并选择库。之后点击应用应该可以安装 Altair 及其依赖项。可以按照同样的方法安装示例数据集 vega_datasets 。
一旦成功安装,返回主页并确保您处于正确的环境*。* 你应该能够启动 Jupyter Notebook 或 JupyterLab,并执行示例库中的任何代码。
从 Anaconda Navigator 启动 JupyterLab 或 Jupyter Notebook
牛郎星图表基础指南
牛郎星官方用户指南里有很多概念,但是数据 , 标志 , 编码 是基本的。理解以下概念应该足以让您创建基本的交互式图表。
数据
Altair 内部使用的数据以 Pandas DataFrame 格式存储,但有四种方式可以传入:
- 作为熊猫的数据框架
- 作为数据或相关对象
- 作为指向 json 或 csv 格式文件的 url 字符串
- 作为支持 geo_interface(例如 Geopandas 地理数据框架、 Shapely Geometries 、 GeoJSON 对象)的对象
下面是一个导入 Pandas 和 Altair 的示例,并创建一个简单的数据帧来可视化,在列 col-1 中有一个分类变量,在列 col-2 中有一个数字变量:
**import altair as alt
import** **pandas** **as** **pd**data = pd.DataFrame({'col-1': list('CCCDDDEEE'),
'col-2': [2, 7, 4, 1, 2, 6, 8, 4, 7]})
chart = alt.Chart(data)
马克斯(英格兰人姓氏)
选择数据后,您需要选择各种图表,如条形图、折线图、面积图、散点图、直方图和地图。mark
属性指定了这些属性应该如何在图上精确地表示。Altair 提供了许多基本标记属性:
牛郎星基本标志
除基本标记外,它还提供以下复合标记:
牛郎星复合标志
有了上面的图表对象,我们现在可以指定我们希望数据如何可视化。这是通过Chart.mark_*
完成的。例如,我们可以使用mark_point()
将数据显示为一个点。
import altair as alt
import pandas as pddata = pd.DataFrame({'a': list('CCCDDDEEE'),
'b': [2, 7, 4, 1, 2, 6, 8, 4, 7]})
chart = alt.Chart(data)
**alt.Chart(data).mark_point()**
通过执行上面的代码,它应该给你一个图表:
我们获得单点显示的原因是渲染由数据集中每行一个点组成,所有点都绘制在彼此之上,因为我们还没有指定这些点的位置。这将通过编码解决。
编码
在 Altair 中,编码是数据到视觉属性的映射,比如轴、标记的颜色、标记的形状等等。编码方法Chart.encode()
定义了图表显示的各种属性,它是创建有意义的可视化的最重要的功能。官方用户指南提供了一长串受支持的属性。以下是最基本的编码属性,了解它们应该足以让您创建基本的图表。
位置通道
x
:x 轴数值y
:y 轴数值row
:分面绘图的行column
:分面绘图的列
标记属性通道
color
:标记的颜色opacity
:标记的不透明度shape
:标记的形状size
:标记的大小
文字频道
text
:用于标记的文本
数据类型
quantitative
:速记码 Q ,连续实数值ordinal
:简写代码 O ,离散订购数量nominal
:简写代码 N ,离散订购数量temporal
:速记代码 T ,时间或日期值
为了直观地将这些点从代码中分离出来,我们可以将各种编码通道,或者简称为通道映射到数据集中的列。例如,我们可以用x
通道对数据的变量col-1
进行编码,该通道代表点的 x 轴位置。这可以通过[**Chart.encode()**](https://altair-viz.github.io/user_guide/generated/toplevel/altair.Chart.html#altair.Chart.encode)
方法直接完成:
import altair as alt
import pandas as pddata = pd.DataFrame({'**col-1**': list('CCCDDDEEE'),
'**col-2**': [2, 7, 4, 1, 2, 6, 8, 4, 7]})
chart = alt.Chart(data)
alt.Chart(data).mark_point()**.encode(
x='col-1',
y='col-2'
)**
这是输出
让图表互动
除了基本的图表,Altair 的一个独特功能是用户可以与图表进行交互,包括平移、缩放和选择一系列数据等控件。
在主题后面,只需调用interactive()
模块就可以实现平移和缩放。例如:
import altair as alt
import pandas as pddata = pd.DataFrame({'col-1': list('CCCDDDEEE'),
'col-2': [2, 7, 4, 1, 2, 6, 8, 4, 7]})
chart = alt.Chart(data)
alt.Chart(data).mark_point().encode(
x='col-1',
y='col-2'
)**.interactive()**
Altair 还提供了用于创建交互式图像的选择 API。在selection()
功能中,我们可以制作一些更酷的高级功能,比如本文开头所示的 GIF 允许对选定的数据点进行分析并生成实时直方图。
逐步构建交互式图表
有了牛郎星的基础知识,我们来做一个互动图。
对于本教程,我们将使用来自 vega_datasets 中示例数据集中的汽车数据,
from vega_datasets import datacars = data.cars()
首先,我们将使用[**selection_interval()**](https://altair-viz.github.io/user_guide/generated/api/altair.selection_interval.html#altair.selection_interval)
功能创建一个区间选择:
brush = alt.selection_interval()
我们现在可以通过设置selection
属性将这个画笔绑定到我们的图表:
alt.Chart(cars).mark_point().encode(
x='Miles_per_Gallon:Q',
y='Horsepower:Q',
color='Origin:N'
)**.add_selection(
brush
)**
上面的结果是一个图表,它允许您单击并拖动来创建一个选择区域,并在创建区域后移动该区域。这很简洁,但是这个选择实际上并没有做任何事情。
添加选择的结果()
要使用这个选项,我们需要在图表中以某种方式引用它。这里,我们将使用[**condition()**](https://altair-viz.github.io/user_guide/generated/api/altair.condition.html#altair.condition)
函数来创建一个条件颜色编码:我们将把选择中的点的颜色绑定到"Origin"
列,并将选择之外的点的颜色设置为"lightgray"
:
alt.Chart(cars).mark_point().encode(
x='Miles_per_Gallon:Q',
y='Horsepower:Q',
**color=alt.condition(brush, 'Origin:N', alt.value('lightgray'))**
).add_selection(
brush
)
条件()的结果
接下来,我们创建一个mark_bar()
图表
alt.Chart(cars).mark_bar().encode(
y='Origin:N',
color='Origin:N',
x='count(Origin):Q'
)
牛郎星条形图
为了将条形图与之前的散点图关联起来,我们需要使用transform_filter()
并传递同一个brush
。此外,对于组合多选图表,我们还需要为它们分别创建变量,并使用组合多选&
。
**points =** alt.Chart(cars).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color=alt.condition(brush, 'Origin:N', alt.value('lightgray'))
).add_selection(
brush
)**bars =** alt.Chart(cars).mark_bar().encode(
y='Origin:N',
color='Origin:N',
x='count(Origin):Q'
).**transform_filter(
brush
)****points & bars**
而且,就是这样。这是输出
这是完整的代码:
学习建议
本文是一个快速教程,主要是给大家展示这个优秀的数据可视化库。学习没有捷径。你必须看文档,源代码,研究相关的例子,并在实践中应用它们。
尽情享受吧!
仅此而已。感谢阅读。
关于 Altair 交互式数据可视化的更多内容,您可以看看
使用 Altair 创建不到 30 行代码的交互式复合图表
towardsdatascience.com](/interactive-data-visualization-for-exploring-coronavirus-spreads-f33cabc64043)
新冠肺炎数据中心的 Python 接口
统一数据集有助于更好地了解新冠肺炎。
编者注: 走向数据科学 是一份以研究数据科学和机器学习为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
图片来自 Pixabay 的米洛丝拉娃·克里斯诺娃
新冠肺炎数据中心的目标是通过收集世界范围内的精细案例数据,结合有助于更好地了解新冠肺炎的外部变量,为研究社区提供一个统一的数据集。请同意使用条款,并在使用时引用以下参考:
参考
Guidotti,e . Ardia,d .(2020 年)。
https://doi.org/10.21105/joss.02376 数据中心
开源软件杂志,5(51):2376
T37
设置和使用
从管道安装
pip install covid19dh
导入主功能covid19()
from covid19dh import covid19
x, src = covid19()
返回值
函数covid19()
返回 2 个熊猫数据帧:
- 数据和
- 对数据源的引用。
参数化
国家
国家名称(不区分大小写)或 ISO 代码(字母 2、字母 3 或数字)的列表。ISO 代码列表可在的处找到。
从特定国家获取数据:
x, src = covid19("USA") # Unites States
同时指定多个国家:
x, src = covid19(["ESP","PT","andorra",250])
如果省略country
,则返回整个数据集:
x, src = covid19()
原始数据
合乎逻辑。跳过数据清理?默认True
。如果是raw=False
,则通过用NaN
值填充缺失的日期来清除原始数据。这确保了所有地点共享相同的日期网格,并且没有一天被跳过。然后,NaN
值被替换为之前的非NaN
值或0
。
x, src = covid19(raw = False)
日期过滤器
日期可以用datetime.datetime
、datetime.date
或格式YYYY-mm-dd
中的str
指定。
from datetime import datetime
x, src = covid19("SWE", start = datetime(2020,4,1), end = "2020-05-01")
水平
整数。数据的粒度级别:
- 国家一级
- 州、地区或县一级
- 城市或自治市一级
from datetime import date
x, src = covid19("USA", level = 2, start = date(2020,5,1))
隐藏物
合乎逻辑。内存缓存?显著提高连续呼叫的性能。默认情况下,启用使用缓存数据。
可以通过以下方式禁用缓存(例如,对于长时间运行的程序):
x, src = covid19("FRA", cache = False)
过时的
合乎逻辑。检索在end
日期生成的数据集快照,而不是使用最新版本。默认False
。
例如,获取 2020 年 4 月 22 日可访问的美国数据类型
x, src = covid19("USA", end = "2020-04-22", vintage = True)
葡萄酒数据在一天结束时收集,但在所有时区的一天结束后,会延迟大约 48 小时发布。
因此,如果vintage = True
未置位,但end
未置位,则发出警告并返回None
。
x, src = covid19("USA", vintage = True) # too early to get today's vintageUserWarning: vintage data not available yet
数据源
数据源作为第二个值返回。
from covid19dh import covid19
x, src = covid19("USA")
print(src)
结论
新冠肺炎数据中心协调了疫情各地的大量异构数据。它代表了新冠肺炎在开放公共数据标准和共享方面的首次努力。使用新冠肺炎数据中心的出版物可在此处获得。
感谢
新冠肺炎数据中心得到了加拿大数据评估研究所的支持。 covid19dh 包是由马丁·贝内什开发的。
[1]吉多蒂,即阿尔迪亚,d .(2020)。新冠肺炎数据中心,《开源软件杂志》,5(51):2376
Python 即将受到挤压
Python 在过去十年统治了数据科学和机器学习,但 Julia 和 Swift 准备废黜这一王者
Jakub Kapusnak 在 Foodiesfeed 上的照片
Python 是在 20 世纪 90 年代作为通用编程语言发布的。
尽管 Python 语法简洁,但它在第一个十年的曝光率并不令人鼓舞,它也没有真正进入开发人员的工作空间。Perl 是首选的脚本语言,Java 已经成为面向对象编程领域的首选。当然,任何语言都需要时间来成熟,只有当它比现有工具更适合某项任务时才会被采用。
对于 Python 来说,这一时刻在 21 世纪初首次到来,当时人们开始意识到它比 Perl 更容易学习,并提供了与其他语言的互操作性。
这种认识导致大量开发人员将 Python 整合到他们的应用程序中。Django 的出现最终导致了 Perl 的灭亡,Python 开始获得更多的动力。尽管如此,它的受欢迎程度甚至不如 Java 和 JavaScript,这两种语言都比 Python 更新。
快进到现在,根据 StackOverflow 开发者调查 2019 ,Python 已经超过 Java 成为第二大最受欢迎的语言。
它也是过去十年中发展最快的编程语言。Python 的流行与 2010 年代大数据的出现以及机器学习和人工智能的发展有很大关系。企业迫切需要一种低门槛的快速开发语言,以帮助管理大规模数据和科学计算任务。Python 非常适合所有这些挑战。
除了这些有利因素之外,Python 还是一种支持动态类型的解释型语言。更重要的是,它得到了谷歌的支持,谷歌为 Tensorflow 投资了 Python,这使它成为数据分析、可视化和机器学习的首选语言。
然而,尽管在本世纪初对机器学习和人工智能的需求不断增长,Python 不会存在太久。像每一种编程语言一样,它也有自己的弱点。这些弱点使得它很容易被更适合企业要求的普通任务的语言所取代。尽管有 R 的存在,但 Swift、Julia 和 Rust 等新语言的出现实际上对当前的数据科学之王构成了更大的威胁。
Rust 仍在试图赶上机器学习社区,因此我相信 Swift 和 Julia 是将取代 Python 并最终统治数据科学的语言。我们来看看为什么 odds 不利于 Python。
Python 缺乏类型安全,速度非常慢
一切美好的事物都是有代价的,Python 的动态类型化自然也不例外。它妨碍了开发人员,尤其是在生产环境中运行代码时。动态类型化使得在不定义类型的情况下快速编写代码变得容易,这增加了遇到运行时问题的风险,尤其是当代码库大小增加时。编译器很容易发现的错误在 Python 中可能无法识别,导致生产中的障碍,并最终减缓大规模应用程序的开发过程。
更糟糕的是,与编译后的代码不同,Python 的解释器在执行时分析每一行代码。这导致了一个开销,与其他语言相比,性能明显降低。
Julia 可以让你避免这些问题。尽管是动态类型的,但它有一个实时编译器。JIT 编译器要么在执行之前生成机器码,要么使用以前存储的、缓存的编译,这使得它与静态类型语言一样具有高性能。更重要的是,它有一个被称为多重分派的关键特性,类似于 OOPs 的函数重载,尽管是在运行时。多重分派的强大之处在于它能够处理不同的参数类型,而不需要创建单独的函数名或嵌套的 if 语句。这有助于编写紧凑的代码,这是数值计算中的一大胜利,因为与 Python 不同,您可以轻松地扩展解决方案来处理所有类型的参数。
更好的是,Swift 是一种静态类型语言,并且由于其 LLVM(低级虚拟机)编译器而得到了高度优化。LLVM 使快速编译成汇编代码成为可能,使 Swift 超高效,几乎和 c 一样快。此外,Swift 还拥有更好的内存安全和管理工具,称为自动引用计数。与垃圾收集器不同,ARC 更具确定性,因为它会在引用计数为零时回收内存。
作为提供类型注释的编译语言,Swift 和 Julia 在开发上比 Python 快得多,也健壮得多。仅这一点就足以推荐他们使用旧语言,但是还有其他因素需要考虑。
Python 在并行性方面有局限性
如果缓慢不是 Python 最明显的缺点,那么这种语言在并行计算方面也有局限性。
简而言之,Python 使用了 GIL(全局解释器锁),它可以防止多个线程同时执行,以便提升单线程的性能。这个过程是一个很大的障碍,因为这意味着开发人员不能使用多个 CPU 内核进行密集计算。
我同意一种常见的观点,即我们目前在利用 Python 与 C/C++库(如 Tensorflow 和 PyTorch)的互操作性方面做得很好。但是 Python 包装器并不能解决所有的调试问题。最终,当检查底层底层代码时,我们会退回到 C 和 C++。从本质上讲,我们不能在底层利用 Python 的优势,这就把它排除在外了。
这个因素很快就会在 Python 的没落和 Julia 和 Swift 的崛起中起到决定性的作用。Julia 是一种专门为解决 Python 缺点而设计的语言。它主要提供了三个特性:协同程序(异步任务)、多线程和分布式计算——所有这些都展示了并发和并行编程的巨大可能性。这种结构使 Julia 能够以远高于 Python 的速度执行科学计算和解决大数据问题。
另一方面,Swift 拥有开发移动应用程序所需的所有工具,并且在并行计算方面没有任何问题。
Swift 和 Julia 拥有 Python 的互操作性和强大的支持
尽管 Python 在速度、多线程和类型安全方面存在不足,但它仍然拥有一个庞大的生态系统,拥有大量的库和包。可以理解的是,Swift 和 Julia 在机器学习领域仍然是婴儿,并且只拥有有限数量的库。然而,它们与 Python 的互操作性大大弥补了 Julia 和 Swift 中库支持的不足。
Julia 不仅让程序员使用 Python 代码(反之亦然),还支持与 C、R、Java 以及几乎所有主流编程语言的互操作性。这种多功能性肯定会给这种语言一个很好的推动,并增加它在数据科学家中迅速采用的机会。
另一方面,Swift 通过 PythonKit 库提供了与 Python 的互操作性。Swift(源自苹果)最大的卖点是它从谷歌那里得到的强大支持,谷歌几十年前就完全支持 Python。看看形势是如何转变的!
此外,Swift 的创始人克里斯·拉特纳现在正在谷歌的人工智能大脑团队工作,这一事实表明 Swift 正在被认真培养为 Python 在机器学习领域的替代品。Tensorflow 团队投资 Swift 的 S4TF 项目进一步证明了该语言不仅仅被视为 Python 的包装器。相反,Swift 由于其差分编程支持和在 C 等底层工作的能力,将有可能被用来取代底层的深度学习工具。
结论
随着数据规模的不断增大,Python 的致命弱点很快就会被发现。易用性和快速编写代码的能力至关重要的日子已经一去不复返了。速度和并行计算是游戏的名字,而更通用的语言 Python 将不再解决这个问题。不可避免的是,当朱莉娅和斯威夫特看起来像是接班人的时候,这种感觉会逐渐消失。
值得注意的是,Python 作为一种编程语言不会很快消失。相反,它只会在数据科学中占据次要地位,因为更专门为深度学习设计的语言将占主导地位。
本文原载于内置的。
Python 比 r 好。
原因如下。
戴维·克洛德在Unsplash【1】上拍摄的照片。
目录
- 介绍
- 原因如下
- 摘要
- 参考
介绍
虽然说 Python 比 R 好对我来说是真的,但对你来说可能不是真的。出于各种原因,你当然会认为 R 比 Python 更有用。即使你反对我的声明,我仍然希望开始一个对话,让我们都能看到两种编程语言的好处。对于数据科学家来说,我相信 Python 比 R 有更多的好处。我确实意识到 R 有一些独特而强大的统计库,很可能会盖过 Python 库:然而;通过使用 Python,整个数据科学过程能够与数据工程师、软件工程师和机器学习工程师一起扩展,从而获得更多好处。
下面,我将讨论为什么我认为 Python 比 r 更好的五个主要原因。这些原因包括:可伸缩性、Jupyter 笔记本、库包、集成以及成为跨职能团队成员的能力。
原因如下
- 扩展性
可伸缩性是在数据科学中使用的一个巨大优势。因为大多数数据科学家经常与工程部门的其他员工一起工作,建模可以变得更容易部署,模型的一般、整体流程也是如此。例如,一个典型的数据科学家可能只专注于执行建模,甚至是一次性的输出。然而,在建模之前有一个步骤,你很可能需要在训练你的机器学习模型之前完成。这一步是数据工程部分。在这个过程中,您可以从 SQL 数据库中自动读入新数据,以便您的模型在训练时总是最新的。流程的另一面是部署方面。第一次部署一个模型可能是相当令人生畏的,特别是因为它在学校里的教授不像建模过程那么多。
软件工程师和机器学习工程师可以和你并肩工作,因为 Python。
您可以创建气流定向非循环图(DAG ),当特定计划中有新数据或满足某些参数时,该图可以自动训练模型(例如,如果我们获得 100 条新的传入数据记录,则仅训练该模型)。一旦模型被训练,它可以评估新的数据,然后可以通过使用 Python 将这些数据输出到 SQL 表中。
- Jupyter 笔记本
或者另一个类似的数据科学可视化工具,能够解释 Python。您可以运行代码单元、添加注释、创建标题,以及添加可以改进笔记本功能的小部件。你在这里写和分享的代码就是 Python。能够在 Jupyter 笔记本上用这种编程语言编码是数据科学家的一大胜利。
- 库包
有几个功能强大的常用包可以用 Python 访问。想到的一些是 sklearn(也称为 sci-kit learn)和 TensorFlow。
sk learn【2】
这个强大的数据科学库打包了分类和回归模型,随时可用于您的数据集。
— 分类
Sklearn 对分类的定义是:识别一个物体所属的类别。一些流行的算法包括支持向量机(SVM)、最近邻和随机森林。Sklearn 还概述了垃圾邮件检测和图像回归,作为他们最受欢迎的应用程序用例。
— 回归
Sklearn 对回归的定义是:预测一个与对象相关联的连续值属性。流行的回归算法包括支持向量回归(SVR)和最近邻法,以及药物反应和股票价格等应用。
张量流【3】
对于深度学习,这个库是我建模更复杂情况的首选。人们可以用这个流行而强大的库进行的一些主要项目有:神经网络、一般对抗网络和注意力集中的神经机器翻译。
- 集成
因为我在大部分数据科学项目中使用 Python,所以我成功地集成了模型。py 文件转换成面向对象的编程格式。这些文件是以模块化的方式有条不紊地开发的。用 Python 调用 API 有些简单,因为网站上有很多文档可以帮助获取网站/公司数据。
- 交叉功能
这个原因在某种程度上是可伸缩性和集成的结合。如果您想在本地执行数据科学流程,并将结果交给利益相关方,这很好,但是使用 Python,您可以与来自工程领域的不同专家一起做更多事情。
当我第一次开始编码时,是在 R 中,当我为了部署的目的向数据工程师和软件工程师展示我的过程和代码时,需要一些额外的时间来准确描述代码背后的数据科学。
我还会发现,与我一起工作的大多数帮助我部署模型的工程师已经在使用 Python,因此他们可以相当容易地翻译我的数据科学代码,即使他们并不完全理解模型是如何工作的。
摘要
克里斯里德在Unsplash【4】上的照片。
如您所见,选择使用 Python 的数据科学家有很多好处。虽然这两种编程语言都非常有用和成功,但我从个人经验中发现 Python 比 r 更好。这些主要原因包括但不限于:可伸缩性、Jupyter 笔记本、库包、集成和交叉功能。最终,语言的选择取决于数据科学家,但本文的目标是展示我如何使用 Python 进行数据科学家项目,以及为什么使用 Python 比 R 编程更好。
我希望你觉得这篇文章既有趣又有用。感谢您的阅读!
参考
[1]照片由 David Clode 在Unsplash(2018)上拍摄
[2] sklearn, sklearn 主页,(2020)
[3] TensorFlow, TensorFlow 主页,(2020)
[4]Chris Ried 在 Unsplash 上拍摄的照片,(2018)
Python 正在慢慢失去它的魅力
意见
编程语言的瑞士军刀有它的问题,可能会被其他更适合这项任务的语言所取代
塔玛拉·戈尔在 Unsplash 上的照片
自从 Python 在 20 世纪 90 年代早期发布以来,它已经产生了很多宣传。当然,编程社区至少花了 20 年才意识到它的存在,但从那以后,它的受欢迎程度已经远远超过了 C、C#、Java 甚至 Javascript。
虽然 Python 主导了数据科学和机器学习领域,并且在某种程度上主导了科学和数学计算领域,但与 Julia、Swift 和 Java 等新语言相比,它也有自己的缺点。
是什么让 Python 如此受欢迎?
Python 的飞速发展背后的一个主要驱动点是它的易学性和易用性,这使得它对初学者非常有吸引力,甚至对那些因为像 C/C++这样的语言的艰深、陌生的语法而回避编程的人也是如此。
这种语言的核心是广泛强调代码的可读性。凭借其简洁而富于表现力的语法,它允许开发人员表达想法和概念,而无需编写大量代码(如 C 或 Java 等低级语言)。鉴于其简单性,Python 可以与其他编程语言无缝集成(比如将 CPU 密集型任务卸载到 C/C++ ),使其成为多语言开发人员的额外收获。
Python 通用性的另一个原因是它被企业(包括 FAANG)和无数小型企业大量使用。今天,你会发现你能想到的几乎任何东西的 Python 包——对于科学计算,你有用于机器学习的 Numpy 、 Sklearn 和用于计算机视觉的 Caer (我的计算机视觉包)。
用于高性能人工智能研究的轻量级计算机视觉库。Caer 包含强大的图像和视频处理操作…
github.com](https://github.com/jasmcaus/caer)
Python 有弱点
很慢,非常慢
尼克·艾布拉姆斯在 Unsplash 上拍摄的照片
这可能是显而易见的。速度通常被认为是开发人员的主要关注点之一,并且可能会持续一段不可预见的时间。
Python“慢”的主要原因有两个——Python 被解释为而不是编译,最终导致执行时间变慢;以及它是动态类型化的事实(变量的数据类型由 Python 在执行过程中自动推断)。
事实上,这种认为“Python 很慢”的观点在初学者中有很大的影响。是的,是真的。但只是部分地。
以 TensorFlow 为例,这是一个用 Python 编写的机器学习库。这些库实际上是用 C++编写的,并在 Python 中可用,在某种程度上形成了围绕 C++实现的 Python“包装器”。Numpy 也是如此,在某种程度上,甚至 Caer 也是如此。
它有一个 GIL
Python 缓慢的主要原因之一是 GIL(全局解释器锁)的存在,它一次只允许一个线程执行。虽然这提高了单线程的性能,但它限制了并行性,开发人员不得不实施多处理程序而不是多线程程序来提高速度。
不是内存密集型任务的最佳选择
当对象超出范围时,Python 会自动进行垃圾收集。它旨在消除 C 和 C++在内存管理方面的复杂性。由于指定数据类型的灵活性(或缺乏灵活性), Python 消耗的内存量可能会迅速爆炸。
此外,Python 可能没有注意到的一些 bug 可能会在运行时突然出现,最终会在很大程度上减慢开发过程。
在移动计算领域表现不佳
照片由 Yura Fresh 在 Unsplash 上拍摄
随着从桌面到智能手机的大规模转移,显然需要更健壮的语言来为移动设备构建软件。虽然 Python 在桌面和服务器平台上有相当大的代表性,但由于缺乏强大的移动计算处理,它往往会在移动开发中失利。
近几年来,这个领域有了很大的进步,但是这些新增加的库甚至不能与他们的强劲竞争对手如 Kotlin、Swift 和 Java 相提并论。
其他语言的兴起
最近,像 Julia、Rust 和 Swift 这样的新语言已经出现在雷达上,从 Python、C/C++和 Java 中借用了许多好的设计概念— Rust 非常好地保证了运行时的内存安全和并发性,并提供了与 WebAssembly 的一流互操作性; Swift 由于支持 LLVM 编译器工具链,几乎和 C 一样快,而Julia为 I/O 密集型任务提供异步 I/O,速度快得惊人。
结论
Python 从来不是为了成为最好的编程语言而构建的。它从来就不是为了应对 C/C++和 Java 而构建的。它是一种通用编程语言,强调人类可读的、以英语为中心的语法,允许快速开发程序和应用程序。
Python 和其他语言一样,归根结底是一种工具。有时候,它是最好的工具。有时候不是。最常见的是“还行”。
那么,Python 作为一种编程语言,是不是正在走向灭亡?
我不这么认为。
它正在失去魅力吗?
啊,也许有一点。就一点点。
用于自然语言处理的 Python 库
用于自然语言处理的流行 python 库概述
用于自然语言处理的 Python 库
“Python 从一开始就是 Google 的重要组成部分,并且随着系统的成长和发展而保持不变。如今,数十名谷歌工程师使用 Python,我们正在寻找更多掌握这种语言的人。”
-彼得·诺威格,谷歌搜索质量总监T5
ython 是目前世界上最热门的编程语言之一,因为它可以优雅地与其他编程语言集成,并作为首选编程语言完美地融入大多数新项目理念。
Python 也是人工智能社区中一种非常受好评的语言,这使得它成为人工智能的几个分支的首选编程语言,如软计算、机器学习、自然语言处理等。
随着未来越来越倾向于采用人工智能和智能解决方案,开发不仅能理解我们的命令,还能与我们自然交流的系统的需求越来越高。
什么是 NLP?
没有单词和驱动这些单词的语法,任何语言都是不完整的。正如人与人之间的交流需要语言和符号一样,与计算机的互动也是如此。
通过点击选项与计算机进行交互的传统方法正慢慢被一种更无缝的方法淘汰,这种方法包括对话。这种现代的交流方式包括以更自然的方式与计算机交谈,因为我们倾向于用语言与其他人交谈。
作为人工智能的一个分支,自然语言处理定义了人类如何更直观地与计算机互动背后的科学。
这样一个领域背后的目的是确定如何让计算机理解和理解除了通常和合理定义的指令集之外的人类常用语言。
作为人工智能的一部分,NLP 在很大程度上依赖于机器学习,NLP 的过程是这样的:
●捕捉人类输入,包括文本输入或语音输入
●将语音数据转换成文本
●使用语法、解析技术、语义和类似方法处理文本,以识别数据的含义
●通过在屏幕上显示或通过音频播放,将处理后的输出传递给人类
用于自然语言处理的 Python 库
自然语言处理被认为是制造智能系统的许多关键方面之一。通过使用从现实世界中收集的数据来训练您的解决方案,您可以使其更快、更贴近用户,从而对您的客户群产生重要的洞察力。
在本文中,我们将了解 Python 如何提供一些最有用、最强大的库,以便在项目中利用自然语言处理的能力,以及它们的确切用途。
●空间
空间(来源)
Python 中工业级自然语言处理的开源库。
通常被认为是高级自然语言处理的专业级 Python 库,spaCy擅长处理难以置信的大规模信息提取任务。
spaCy 使用 Python 和 Cython 构建,结合了两种语言的优点、Python 的便利性和 Cython 的速度,提供了一流的 NLP 体验。spaCy 是一个简洁的库,旨在通过最大限度地减少花费在日常任务上的时间来完成工作。spaCy 的主要收获是:
●词性标注
●符号化
●依存解析
●句子分割
●实体和句子识别
●与深度学习无缝集成
●清理和规范化文本的方法
资源-
- 空间文档 —官方文档和快速入门指南。
- SpaCy NLP 简介 —展示 SpaCy 功能的简短教程。
最重要的概念,用简单的术语解释,不管你是 spaCy 新手,还是只想温习一些…
空间. io](https://spacy.io/usage/spacy-101/)
● CoreNLP
Stanford CoreNLP 是一套为在你的项目中实现自然语言处理而构建的工具。最初是用 Java 编写的,CoreNLP 可以和其他语言一起工作,比如Python、JavaScript 等等。
它提供了几个语言特性,比如表达情感、提取实体之间的关系、标记句子结构、提供单词的基本形式等等。
用更花哨的术语来说,这些功能可以转化为词汇化、词性和词形标注、命名实体识别、标记化和句子拆分等更多功能。
如果您正在寻找一个 NLP 工具包,它是一个现代化的、健壮的、具有各种语法分析工具的工具包,这些工具定期更新并提供高质量的分析,那么它是一个完美的选择。
CoreNLP 的灵活特性允许它与其他语言很好地集成,使它成为满足您需求的平滑可扩展的功能性 NLP 选项。
资源-
- CoreNLP 文档 —官方文档和资源汇编。
- CoreNLP 的 Python 包装器列表 —由斯坦福 NLP 保持最新。
● NLTK — T 最广为人知的 NLP 图书馆
自然语言工具包的简称,NLTK 是 Python 的领先的和最好的自然语言处理库之一。它有超过 100 个语料库和相关的词汇资源,如 WordNet、Web 文本语料库、NPS Chat、SemCor、FrameNet 等等。
NLTK 的目标是通过为 NLP 库提供分类、词干、标记、解析、分类语义推理和包装器等特性,使学习和使用计算语言学变得更加容易。
这是一个免费的开源库,可以在 Windows、Mac OS 和 Linux 上使用,有大量的教程可以让你顺利进入 NLP 的世界。
使用 NLTK 可以做的事情—
NLTK —对一些文本进行标记和标记(源)
NLTK —识别命名实体(源)
资源—
● Gensim
Gensim 是用 Python 编写的用于主题建模、相似性检索和自然语言处理的库。
由雷迪姆·řehůřek****于 2009 年开发的 Gensim 旨在擅长两件事,一个是自然语言处理,另一个是信息检索。它处理特定类别的大量数据,并从中提供非常精确的见解。
Gensim 为几种流行的算法提供了独立于内存的实现能力,例如潜在狄利克雷分配****【LDA】****随机投影(RP)**潜在语义分析(LSA/LSI/LVD) 和分层狄利克雷过程(HDP)** 等等。
Gensim 附带了流畅的 API 支持,使与其他编程语言的集成变得轻而易举,而丰富的文档和教程则在您的编程之旅中为您提供指导。使用 Gensim 的先决条件是使用 NumPy 和 Scipy 包。
资源-
- gensim 文档 —官方文档和教程。教程页面非常有用。
● PyNLPI
关于 FoLiA XML 和许多其他常见 NLP 格式(CQL、Giza、Moses、ARPA、Timbl 等)的广泛功能。).
读作“ 菠萝”,是 Python 的开源自然语言处理库。PyNLPl 是各种任务的理想选择,包括构建简单模型、提取 n 元语法和频率列表,并支持复杂的数据类型和算法。
它还配备了对标准 NLP 文件格式的支持,如摩西、 Timbl 、吉萨等等。PyNLPl 的库由几个包组成,这些包详细介绍了它所提供的功能。
以下是其中的几个软件包:
● pynlpl.datatypes 增加了额外的数据类型
● pynlpl.formats.giza,用于从 GIZA++单词对齐中读取数据
● pynlpl.formats.tmbl 允许读取 Timbl 数据
● pynlpl.textprocessors 作为简单的标记器和 n-gram 提取
● pynlpl.formats.cgn 用于解析 cgn 词性标签
● 图案
Web(数据)挖掘/爬行和常见的 NLP 任务。
Pattern 主要是 Python 的一个 web 挖掘模块,包含了用于许多目的的工具,如数据挖掘、自然语言处理、机器学习和网络分析。
专注于模式的 NLP 方面,它很好地配备了任何 NLP 的基本功能,例如词性标记、n-grams、情感分析、WordNet、文本分类和标记化等等。
它完整地记录了超过 350 个单元测试和超过 50 个例子,让你马上开始使用它。对 web APIs 的支持可以轻松地与其他编程语言集成,从而扩展模式的功能。
谷歌趋势—一段时间内的兴趣模式
谷歌趋势-模式(来源)
●多语言
多语种和音译能力。
由 Rami Al-Rfou 开发的 Polyglot 是一个 Python 自然语言处理库,对于必须处理大量语言的应用程序来说是完美的。
由于支持一些传统的自然语言处理功能,如标记化、语言检测、词性标注等,它的每个自然语言处理功能都因支持多种语言而得到进一步增强。
对多种语言的支持使其成为本地化扮演重要角色的可行选择。它附带了详细的文档,简化了任何人的进入过程。
● TextBlob
Textblob ( 源)
Textblob 是另一个开源 Python 库,用于处理基于文本的数据,并通过其 API 提供与其他编程语言的平滑集成。如果您急于执行标准的 NLP 操作,Textblob 可以成为您的救星。它提供了许多自然语言处理库的标准特性,例如:
●词性标注
●情感分析
●分类
●符号化
● n 元语法
●单词变形
● WordNet 集成
●由谷歌翻译支持的语言翻译和检测
●单词和短语频率
●解析
●拼写纠正
●通过扩展添加新的模型或语言
它附带了全面的教程,使新的学习者的学习曲线相对平滑。
资源-
- TextBlob 文档 —官方文档和快速入门指南。
- 使用 TextBlob 的自然语言处理基础知识 —使用 TextBlob 的优秀、简短的 NLP 速成班。
结论
与任何系统的交互都是基本的行为之一,应该始终关注于让这个过程对用户来说尽可能的无缝。随着对话系统逐渐成为标准,我们的解决方案需要识别我们的日常语言。自然语言处理使我们能够为计算机简化这一点,并创造出比今天更智能的下一代解决方案。在这个不断变化的世界中,Python 已经证明了自己有足够的能力来适应、创新和交付解决方案,以解决过去困扰我们的各种现代计算问题。
其他来源—
我希望这篇文章对你有用!如果您有兴趣了解更多信息,以下是附加资源:—
计算机如何理解人类语言
medium.com](https://medium.com/@ageitgey/natural-language-processing-is-fun-9a0bff37854e) [## 🚀Python 中的自然语言处理速度快 100 倍
如何利用空间&快速自然语言处理的一点技巧
medium.com](https://medium.com/huggingface/100-times-faster-natural-language-processing-in-python-ee32033bdced) [## 用于可解释机器学习的 Python 库
4 个用于更好地可视化、解释和诠释模型的库
towardsdatascience.com](/python-libraries-for-interpretable-machine-learning-c476a08ed2c7) [## 数据科学的 10 大 Python 库
为您的数据科学探索提供一些很酷的帮助!
towardsdatascience.com](/top-10-python-libraries-for-data-science-cd82294ec266)
关于作者
克莱尔 D 。在digital ogy—是一个内容制作者和营销人员。这是一个技术采购和定制匹配市场,根据全球各地的特定需求,将人们与预先筛选的&顶尖开发人员和设计师联系起来。连接DigitalogyonLinkedinTwitterinsta gram。**