<(|是什么让你们玩的ag平台|)>

明朝的吴承恩.
其他答案(共2个回答)
的作者是什么朝代
中国明代长篇小说。又题为《忠义水浒传》,通行本简称《水浒》。一般认为是施耐庵著。关于它的作者,明人记载不一。郎瑛《七修类稿》中说:“《三国》、《宋江》二书,乃杭...
当代作家钱钟书的《围城》、巴金的《家》被翻译成七八种文字,在世界范围内有很大影响。鲁迅是世界文化十大名人之一,他的作品应在“世界名著”范围内。
儒家的《论语》,...
明代小说家。字汝忠,号射阳山人。先世江苏涟水人,后徙淮安山阳(今江苏淮安)。出身于一个世代书香而败落为小商人的家庭。曾祖吴铭曾任浙江余姚县学训导,祖父吴贞曾任浙...
最早的《西游记》是没有作者署名的——明代南京有家出版机构叫“世德堂”,老板姓唐,在万历二十年(1592)出版了这部《新刻出像官板大字西游记》,这是我们今天能见到...
答: 妊娠纹如何去掉呢?腾讯新闻好像有一篇文章是说这个的,大家有吗?
答: 鲁迅对老师的印象总体来说是正面的....
答: 为灵魂而艺术
答: [89]他说:“学至于佛则无所学”,以为宋伊川诸儒“皆窃吾佛书”
大家还关注
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区更多频道内容在这里查看
爱奇艺用户将能永久保存播放记录
过滤短视频
暂无长视频(电视剧、纪录片、动漫、综艺、电影)播放记录,
按住视频可进行拖动
&正在加载...
收藏成功,可进入
查看所有收藏列表
当前浏览器仅支持手动复制代码
视频地址:
flash地址:
html代码:
通用代码:
通用代码可同时支持电脑和移动设备的分享播放
用爱奇艺APP或微信扫一扫,在手机上继续观看
当前播放时间:
一键下载至手机
限爱奇艺安卓6.0以上版本
使用微信扫一扫,扫描左侧二维码,下载爱奇艺移动APP
其他安装方式:手机浏览器输入短链接http://71.am/udn
下载安装包到本机:
设备搜寻中...
请确保您要连接的设备(仅限安卓)登录了同一爱奇艺账号 且安装并开启不低于V6.0以上版本的爱奇艺客户端
连接失败!
请确保您要连接的设备(仅限安卓)登录了同一爱奇艺账号 且安装并开启不低于V6.0以上版本的爱奇艺客户端
部安卓(Android)设备,请点击进行选择
请您在手机端下载爱奇艺移动APP(仅支持安卓客户端)
使用微信扫一扫,下载爱奇艺移动APP
其他安装方式:手机浏览器输入短链接http://71.am/udn
下载安装包到本机:
爱奇艺云推送
请您在手机端登录爱奇艺移动APP(仅支持安卓客户端)
使用微信扫一扫,下载爱奇艺移动APP
180秒后更新
打开爱奇艺移动APP,点击“我的-扫一扫”,扫描左侧二维码进行登录
没有安装爱奇艺视频最新客户端?
正在检测客户端...
您尚未安装客户端,正在为您下载...安装完成后点击按钮即可下载
, 可在设置中重新打开噢!
30秒后自动关闭
你们玩ag8卡吗">你们玩ag8卡吗
请选择打赏金额:
播放量数据:快去看看谁在和你一起看视频吧~
更多数据:
您使用浏览器不支持直接复制的功能,建议您使用Ctrl+C或右键全选进行地址复制
安装爱奇艺视频客户端,
马上开始为您下载本片
5秒后自动消失
&li data-elem="tabtitle" data-seq="{{seq}}"& &a href="javascript:void(0);"& &span>{{start}}-{{end}}&/span& &/a& &/li&
&li data-downloadSelect-elem="item" data-downloadSelect-selected="false" data-downloadSelect-tvid="{{tvid}}"& &a href="javascript:void(0);"&{{pd}}&/a&
选择您要下载的《
色情低俗内容
血腥暴力内容
广告或欺诈内容
侵犯了我的权力
还可以输入
您使用浏览器不支持直接复制的功能,建议您使用Ctrl+C或右键全选进行地址复制&figure&&img src=&/50/v2-41d5cab792c200e68f3f7ba5b807dc35_b.jpg& data-rawwidth=&564& data-rawheight=&377& class=&origin_image zh-lightbox-thumb& width=&564& data-original=&/50/v2-41d5cab792c200e68f3f7ba5b807dc35_r.jpg&&&/figure&此文为作者使用Vim近一年来的一些总结. 文章整体叙述一种方法和思路。&p&而不是误导大家,什么配置是最好的,什么插件是最好的, 什么按键是最全面的....&/p&&p&&b&其实,适合自己的,就是最好的!&/b&&/p&&br&&p&在学习Vim的过程中,令我感触最深的无非就是它强大的配置特性,在近一年的时间里,我已经无法适应其它IDE,甚至我完全不想使用鼠标。并且效率越来越高,无论是开发,重构,乃至是自己的开源项目.&/p&&p&以下列出一些总结:&/p&&ol&&li&&u&看别人的配置文件,尤其是那种Geek的配置文件&/u&&/li&&li&&u&在尽量不重写原生键位的情况下,扩展按键方式&/u&&/li&&li&&u&编写,寻找工具函数, 使得很多繁琐的操作得以简化&/u&&/li&&li&&u&只需要你需要的,抛弃你不需要的&/u&&/li&&li&&u&需要自己寻找解决问题的方法&/u&&/li&&/ol&&br&&br&&br&&h2&1. 学习别人的配置文件&/h2&&p&从完全不习惯,到慢慢适应, 熟悉了Vim的一些原生键位后,很多人对于写自己的配置没有头绪.
第一是不知道怎样开始,第二,对于VimL不太了解,这里我不推荐直接看VimL的基础. &/p&&p&这个时候需要先阅读基础的配置,从&b&简单到深入&/b& , &/p&&p&这时候不妨先看看带注释的配置文件:&/p&&p&&a href=&/?target=http%3A//amix.dk/vim/vimrc.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&amix.dk/vim/vimrc.html&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&/p&&p&&b&可能你一懒,就用上了 spf13 , exVim 这样的懒人配置文件,但是我可以负责任的告诉观众们,直接使用别人的配置文件是毫无成长的,或者说你理解不了Vim真正的魅力.&/b&&/p&&br&&p&首先. 我们保证对于最基本的配置有了一定认识,比如你确定你明白了下面配置的意思. 例如:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&& Ignore case when searching
set ignorecase
& When searching try to be smart about cases
set smartcase
& Highlight search results
set hlsearch
&/code&&/pre&&/div&&br&&p&之后我们开始寻找一些其它人的配置文件作为参考,从而认识到更加多的配置属性, 以及配置经验 , 或者直接看内置的help文档也行,
接下来让我们看看YouCompeleteMe 作者 Valloric 的配置文件:&/p&&br&&p&&a href=&/?target=https%3A///Valloric/dotfiles/blob/master/vim/vimrc.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Valloric/dotfiles&i class=&icon-external&&&/i&&/a&&br&&/p&&p&&b&这个配置可以说朴实无华&/b&, 几乎是找不出什么特别的地方, 但是仔细看一下 449 行 -& &a href=&/?target=https%3A///Valloric/dotfiles/blob/master/vim/vimrc.vim%23L449& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Valloric/dotfiles&i class=&icon-external&&&/i&&/a&&/p&&div class=&highlight&&&pre&&code class=&language-vim&&&span&&/span&&span class=&c&&& our &leader& will be the space key&/span&
&span class=&k&&let&/span& mapleader&span class=&p&&=&/span&&span class=&s2&&& &&/span&
&span class=&c&&& our &localleader& will be the '-' key&/span&
&span class=&k&&let&/span& maplocalleader&span class=&p&&=&/span&&span class=&s2&&&-&&/span&
&/code&&/pre&&/div&&br&&p&&b&发现作者将Leader键位映射到了空格&/b&,在编程中我们极少使用的&b&大拇指&/b&一下变成了主力, 并且作为各种指令操作的&b&关键按键&/b&. 令我感到无比惊讶 . 这正是寻找极致优化键位的一种体现, 让配置完全改变了手指的使用习惯!&/p&&br&&br&&h2&2. 在尽量不去改写原生键位的情况下,扩展键位&/h2&&p&在Vim 中, HJKL 键位本身已经把自己需要做的事情care的很好的了,我们不需要再对这些键位进行重写,
但是有些按键就做的不够好。 例如:&/p&&p&g; , g+; 的键位可以让我们快速定位到之前每一步修改的位置 ( 使用 : 查看文档)&/p&&p&&b&但是这个组合按键做的不太好&/b&, 在跳转位置时候没有将窗口视角锁定到屏幕中央. 导致了我们会做一些不必要的翻页动作, 所以我们可以重写它:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&& Format Jump
nnoremap &silent&zz
nnoremap &silent& g, g,zz
&/code&&/pre&&/div&&br&&p&在执行完 之后多添加一步 zz 操作 ( 使用 :help zz 查看文档), 将光标窗口自动滚动定位,使得光标垂直居中.&/p&&p&但是一般来说,&b&我们仅仅只有在这个按键做的不够好的情况下,才使用重写的策略&/b&, 而多数键位是使用扩展的方式( 最大程度上保证向前兼容,遵循渐进增强的原则 )&br&&/p&&p&&b&例如我们可以自定义分屏键位,不需要每次都输入command&/b&:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&& Split fast
nnoremap &leader&\ :vs&CR&
nnoremap &leader&- :sp&CR&
&/code&&/pre&&/div&&br&&br&&h2&3. 编写工具函数+集成组合按键,完成常用操作&/h2&&p&工具是用于解决特定的问题,
例如,如果你需要为Vim 制定一个样式主题, 那么首先你需要知道,文本中的解析 syntax class 名称是什么 ,然后才可以知道,需要给哪个样式定义颜色, 我们定义一个 SynStack函数,用于检测当前光标下的单词,对应于那种syntax class,并输出在laststatus 中:&/p&&div class=&highlight&&&pre&&code class=&language-vim&&&span&&/span&&span class=&c&&& Lookup HighLight Syntax Define&/span&
&span class=&k&&function&/span&&span class=&p&&!&/span& &span class=&p&&&&/span&SID&span class=&p&&&&/span&SynStack&span class=&p&&()&/span&
echo map&span class=&p&&(&/span&synstack&span class=&p&&(&/span&line&span class=&p&&(&/span&&span class=&s1&&'.'&/span&&span class=&p&&),&/span&&span class=&k&&col&/span&&span class=&p&&(&/span&&span class=&s1&&'.'&/span&&span class=&p&&)),&/span&&span class=&s1&&'synIDattr(v:val, &name&)'&/span&&span class=&p&&)&/span&
&span class=&nb&&nnoremap&/span& &span class=&p&&&&/span&leader&span class=&p&&&&/span&yi :&span class=&k&&call&/span& &span class=&p&&&&/span&SID&span class=&p&&&&/span&SynStack&span class=&p&&()&&/span&CR&span class=&p&&&&/span&
&/code&&/pre&&/div&&br&&br&&p&有例如,我们需要快速搜索一个选中的文本 ( 这里需要配合插件Ag) :&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&& for search
function! VisualSelection(direction, extra_filter) range
let l:saved_reg = @&
execute &normal! vgvy&
let l:pattern = escape(@&, '\\/.*$^~[]')
let l:pattern = substitute(l:pattern, &\n$&, &&, &&)
execute 'Ag '.l:pattern
let @/ = l:pattern
let @& = l:saved_reg
endfunction
vnoremap &leader&s :call VisualSelection('ag', '')&CR&
&/code&&/pre&&/div&&br&&p&所以我们应该尽量做到,将一些常用的操作,通过函数+键位映射的方式快速解决.
看到这里你终于知道为什么Vim 可以比IDE 要快.&/p&&br&&br&&h2&4. 只需要你需要的,抛弃你不需要的&/h2&&p&随着NeoVim 的崛起,目前Vim作者加快了迭代的速度,大家可以在这里看到Vim更新的log:&/p&&p&ftp://ftp.vim.org/pub/vim/patches/8.0/README&br&&/p&&br&&p&目前,许多的旧配置中的设置已经被抛弃(或者不生效), 所以压缩精简我们的配置文件就成了当务之急。 &/p&&p&推荐是将一些不必要的或者不使用的插件,设置注释掉,或者删除.&/p&&br&&br&&h2&5.
需要自己寻找解决问题的方法&/h2&&p&Vim中并不是一切都已经为你准备好了 , 需要你自己制定. 当VimL无法满足你的需求时,你可能需要使用外部语言对Vim进行扩展, 比如Python为Vim编写插件, 例如著名的补全插件: &/p&&p&&a href=&/?target=https%3A///Valloric/YouCompleteMe/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Valloric/YouCompleteMe&i class=&icon-external&&&/i&&/a&&/p&&br&&p&Vim 中大部分东西都可以制定,可能只有你想不到,没有做不到,例如让Vim支持文件图标, 看这个项目 &a href=&/?target=https%3A///ryanoasis/vim-devicons& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ryanoasis/vim-devicons&i class=&icon-external&&&/i&&/a& :&/p&&img src=&/v2-36fdfb1ca58ea539b249_b.png& data-rawwidth=&817& data-rawheight=&890& class=&origin_image zh-lightbox-thumb& width=&817& data-original=&/v2-36fdfb1ca58ea539b249_r.png&&&br&&p&由于Vim中没有一个令我觉得满意的字体,于是我自己通过fontforge 重新制定了一个 bdf 字体( 点阵字体 ). 点阵字体的好处自然不用多说,不管在任何分辨率的屏幕下表现是一致的,而且是以像素点来绘制字体,不存在毛边和锯齿,
这样无论是工作在Linux下,还是带R屏的Mac下,都有不错的效果. 字体已开源 - &a href=&/?target=https%3A///DemonCloud/Aix-Vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&DemonCloud/Aix-Vim&i class=&icon-external&&&/i&&/a&
fonts 文件夹中:&/p&&img src=&/v2-2b96bfdeca_b.png& data-rawwidth=&675& data-rawheight=&823& class=&origin_image zh-lightbox-thumb& width=&675& data-original=&/v2-2b96bfdeca_r.png&&&p&完~&/p&
此文为作者使用Vim近一年来的一些总结. 文章整体叙述一种方法和思路。而不是误导大家,什么配置是最好的,什么插件是最好的, 什么按键是最全面的....其实,适合自己的,就是最好的! 在学习Vim的过程中,令我感触最深的无非就是它强大的配置特性,在近一年的…
&figure&&img src=&/50/v2-875c9c3d_b.png& data-rawwidth=&793& data-rawheight=&294& class=&origin_image zh-lightbox-thumb& width=&793& data-original=&/50/v2-875c9c3d_r.png&&&/figure&&p&&b&&u&该文章已移到github,该版本比较旧,请阅读 &a href=&/?target=http%3A//spacevim.org/README_zh_cn/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SpaceVim/SpaceVim&i class=&icon-external&&&/i&&/a&&/u&&/b&&/p&&br&&h3&&b&SpaceVim&/b&&/h3&&img src=&/v2-bee9c49a46947_b.png& data-rawwidth=&1363& data-rawheight=&723& class=&origin_image zh-lightbox-thumb& width=&1363& data-original=&/v2-bee9c49a46947_r.png&&&p&项
页: &a href=&/?target=https%3A//spacevim.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&spacevim.org&i class=&icon-external&&&/i&&/a&&/p&&p&Github
地址 : &a href=&/?target=https%3A///SpaceVim/SpaceVim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SpaceVim/SpaceVim&i class=&icon-external&&&/i&&/a&, 欢迎Star或fork,感谢支持! 使用过程中遇到问题在github提交issue将更容易被关注和修复。我们也欢迎喜欢vim的用户加入我们的QQ群,一起讨论vim相关的技巧,&a href=&/?target=https%3A///%3F_wv%3DD43DB6SG& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&点击加入Vim/SpaceVim用户群&i class=&icon-external&&&/i&&/a&。&br&&/p&&p&SpaceVim 是一个模块化配置集合,包含针对各种语言开发的插件和相应的优化配置。目前支持多种语言的自动补全、语法检测、代码格式化,而且启动速度飞快。SpaceVim的另一核心理念就是按序延迟加载,目前90%的插件都是滞后加载。SpaceVim模块化的思想来源于 spacemacs的layer(模块),将各种功能包装好封装成一个layer,用户根据自己的需要载入相应的layer,实现自定义SpaceVim。&/p&&p&SpaceVim对于新手有着非常友好的界面,界面格局和大多数IDE也比较类似。不过为了更好的体验SpaceVim,建议对于vim需要有一定的了解,如果有一定的英语基础建议阅读这篇关于vim的教程 &a href=&/?target=https%3A///mhinz/vim-galore& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&vim-galore&i class=&icon-external&&&/i&&/a&. &br&&/p&&h4&&b&安装&/b&&br&&/h4&&p&一、Linux 或 Mac 下 SpaceVim的安装非常简单,只需要执行以下命令即可:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&curl -sLf https://spacevim.org/install.sh &span class=&p&&|&/span& bash
&/code&&/pre&&/div&&p&想要获取更多的自定义的安装方式,请参考:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&curl -sLf https://spacevim.org/install.sh &span class=&p&&|&/span& bash -s -- -h
&/code&&/pre&&/div&&br&&p&在初次使用SpaceVim的时候,当你打开vim时,SpaceVim会下载需要的插件,请等待下载过程完成,如果有失败的,可以手动执行 :&/p&&div class=&highlight&&&pre&&code class=&language-vim&&&span&&/span&&span class=&p&&:&/span&&span class=&k&&call&/span& dein#install&span class=&p&&()&/span&
&/code&&/pre&&/div&&p&SpaceVim是一种模块化配置,可以运行在vim或者neovim上,关于vim以及neovim的安装,请参考以下链接:&/p&&blockquote&&p&&a href=&/?target=https%3A///neovim/neovim/wiki/Installing-Neovim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&neovim installation&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///Valloric/YouCompleteMe/wiki/Building-Vim-from-source& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Building Vim from source&i class=&icon-external&&&/i&&/a&&/p&&/blockquote&&p&二、windows系统下的安装步骤:&/p&&ul&&li&Windows 下 vim 用户只需要将本仓库克隆到用户 HOME 目录下的 vimfiles 即可,打开 CMD 默认的目录默认即为 HOME 目录,只需要执行如下命令即可:&/li&&/ul&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&git clone /SpaceVim/SpaceVim.git vimfiles
&/code&&/pre&&/div&&ul&&li&Windows 下 neovim 用户 需要将本仓库克隆到用户 HOME 目录下的 AppData\Local\nvim,想要获取跟多关于 neovim 安装相关的知识,可以访问 neovim 的 wiki, wiki 写的非常详细。打开 CMD 初始目录默认一般即为 HOME 目录,只需要执行如下命令即可: &/li&&/ul&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&git clone /SpaceVim/SpaceVim.git AppData&span class=&se&&\L&/span&ocal&span class=&se&&\n&/span&vim
&/code&&/pre&&/div&&h4&特性&/h4&&ul&&li&以neovim为主的新特性实现&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim%23modular-configuration& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&模块化设置&i class=&icon-external&&&/i&&/a&&/li&&li&依赖 dein.vim 的延迟加载,90%插件延迟加载,启动速度极快&/li&&li&高效,轻量级&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim%23unite-centric-work-flow& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unite为主的工作平台&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim%23awesome-ui& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&优雅的界面&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim%23language-specific-mode& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&针对不同语言开发的优化&i class=&icon-external&&&/i&&/a&&/li&&li&可扩展的补全引擎,vim下为neocomplete, neovim 下为 deoplete&/li&&li&细致的tags管理&/li&&li&轻量级状态栏&/li&&li&优雅的主题&/li&&/ul&&h4&文件结构&/h4&&ul&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&config&i class=&icon-external&&&/i&&/a&/ - Configuration&ul&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/plugins& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&plugins&i class=&icon-external&&&/i&&/a&/ - Plugin configurations&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/mappings.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&mappings.vim&i class=&icon-external&&&/i&&/a& - Key mappings&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/autocmds.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&autocmds.vim&i class=&icon-external&&&/i&&/a& - autocmd group&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/general.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&general.vim&i class=&icon-external&&&/i&&/a& - General configuration&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/init.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&init.vim&i class=&icon-external&&&/i&&/a& - runtimepath initialization&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/neovim.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&neovim.vim&i class=&icon-external&&&/i&&/a& - Neovim specific setup&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/plugins.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&plugins.vim&i class=&icon-external&&&/i&&/a& - Plugin bundles&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/commands.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&commands.vim&i class=&icon-external&&&/i&&/a& - Commands&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/functions.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&functions.vim&i class=&icon-external&&&/i&&/a& - Functions&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/config/main.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&main.vim&i class=&icon-external&&&/i&&/a& - Main config&/li&&/ul&&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/ftplugin& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ftplugin&i class=&icon-external&&&/i&&/a&/ - Language specific custom settings&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/snippets& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&snippets&i class=&icon-external&&&/i&&/a&/ - Code snippets&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/filetype.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&filetype.vim&i class=&icon-external&&&/i&&/a& - Custom filetype detection&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/init.vim& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&init.vim&i class=&icon-external&&&/i&&/a& - Sources config/main.vim&/li&&li&&a href=&/?target=https%3A///SpaceVim/SpaceVim/blob/dev/vimrc& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&vimrc&i class=&icon-external&&&/i&&/a& - Sources config/main.vim&/li&&/ul&&h4&模块化设置&/h4&&ul&&li&SpaceVim 将从 ~/.local.vim 和当前目录的 .local.vim 载入用户配置,(该方式将被舍弃).&/li&&li&SpaceVim 将从 ~/.SpaceVim.d/init.vim 和当前目录的 ./SpaceVim.d/init.vim 载入配置,并且更新 rtp,用户可以在 ~/.SpaceVim.d/
和 .SpaceVim.d/ 这两个文件夹下编辑自己的脚本,和 SpaceVim 的配置文件。&/li&&/ul&&p&示例:&/p&&br&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&& here are some basic customizations, please refer to the top of the vimrc file for all possible options
let g:spacevim_default_indent = 3
let g:spacevim_max_column
let g:spacevim_colorscheme
= 'my_awesome_colorscheme'
let g:spacevim_plugin_manager = 'dein'
& neobundle or dein or vim-plug
& change the default directory where all miscellaneous persistent files go
let g:spacevim_cache_dir = &/some/place/else&
& by default, language specific plugins are not loaded.
this can be changed with the following:
let g:spacevim_plugin_groups_exclude = ['ruby', 'python']
& if there are groups you want always loaded, you can use this:
let g:spacevim_plugin_groups_include = ['go']
& alternatively, you can set this variable to load exactly what you want
let g:spacevim_plugin_groups = ['core', 'web']
& if there is a particular plugin you don't like, you can define this variable to disable them entirely
let g:spacevim_disabled_plugins=['vim-foo', 'vim-bar']
& if you want to add some custom plugins, use this options.
let g:spacevim_custom_plugins = [
\ ['plasticboy/vim-markdown', 'on_ft' : 'markdown'],
\ ['wsdjeg/GitHub.vim'],
& anything defined here are simply overrides
set wildignore+=\*/node_modules/\*
set guifont=Wingdings:h10
&/code&&/pre&&/div&&h4&Unite 为主的工作流&/h4&&ul&&li&&p&列出所有插件,并且可以根据输入的字符模糊匹配,回车将打开对应插件的github网站, 这非常便于临时去github上面找文档,默认的启动快捷键是 :
&leader&lp&img src=&/v2-264e05ced80ed4b0a702f9f47ca4bc45_b.png& data-rawwidth=&1366& data-rawheight=&768& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/v2-264e05ced80ed4b0a702f9f47ca4bc45_r.png&&&/p&&/li&&li&&p&列出所有按键映射以及描述,可以通过输入模糊搜索对应的快捷键,回车即可执行,默认启动该功能的快捷键是: f&space&&img src=&/v2-d0b6cded716f62f47d97_b.png& data-rawwidth=&1366& data-rawheight=&768& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/v2-d0b6cded716f62f47d97_r.png&&&/p&&/li&&li&&p&通过 Unite 列出自己在 github 上面所有的 star 的仓库名称以及描述,模糊搜索,回车通过浏览器打开相应的网站,默认的快捷键是 :&leader&ls&img src=&/v2-b24afc8949e_b.png& data-rawwidth=&1366& data-rawheight=&768& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/v2-b24afc8949e_r.png&&&/p&&/li&&/ul&&h4&Awesome ui&/h4&&ul&&li&outline + filemanager + checker&/li&&/ul&&img src=&/v2-b43c2b5b14b2a8dc64bad04_b.png& data-rawwidth=&1366& data-rawheight=&768& class=&origin_image zh-lightbox-thumb& width=&1366& data-original=&/v2-b43c2b5b14b2a8dc64bad04_r.png&&
该文章已移到github,该版本比较旧,请阅读
SpaceVim项 目 主 页: Github 地址 : , 欢迎Star或fork,感谢支持! 使用过程中遇到问题在github提交issue将更容易被关注和修复。我们也欢迎喜欢vim的用户加入我…
&figure&&img src=&/50/v2-15a3a824f3d8ad032bdae_b.png& data-rawwidth=&593& data-rawheight=&480& class=&origin_image zh-lightbox-thumb& width=&593& data-original=&/50/v2-15a3a824f3d8ad032bdae_r.png&&&/figure&&p&最近在写代码, 编一个 Python 模拟器, 做 simulation, 好不容易用传说中 Python 里速度最快的计算模块 &Numpy& 的写好了, 结果运行起来, 出奇的慢! 因为一次simulation要一个小时, 要不停测试, 所以自己受不了了.. 首先, 我的脑海中的问题, 渐渐浮现出来.&/p&&ul&&li&我知道 Pandas 要比 Numpy 慢, 所以我尽量避免用 Pandas. 但是 Numpy (速度怪兽), 为什么还是这么慢?&/li&&/ul&&p&带有写代码洁癖的我好好给 google 了一番. 第一个出现在我眼前的就是这个文章, &a href=&/?target=http%3A//ipython-books.github.io/featured-01/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Getting the Best Performance out of NumPy&i class=&icon-external&&&/i&&/a&. 所以我也将自己从这个文章中学到的诀窍分享给大家, 并补充一些内容.&/p&&p&&br&&/p&&h2&为什么用 Numpy?&/h2&&img src=&/v2-99ce5e6ec2eaed_b.jpg& data-rawwidth=&400& data-rawheight=&225& class=&content_image& width=&400&&&p&&br&&/p&&p&我们都知道, Python 是慢的, 简单来说, 因为 Python 执行你代码的时候会执行很多复杂的 &check& 功能, 比如当你赋值&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&b&/span&&span class=&o&&=&/span&&span class=&mi&&1&/span&&span class=&p&&;&/span& &span class=&n&&a&/span&&span class=&o&&=&/span&&span class=&n&&b&/span&&span class=&o&&/&/span&&span class=&mf&&0.5&/span&
&/code&&/pre&&/div&&p&这个运算看似简单, 但是在计算机内部, b 首先要从一个整数 integer 转换成浮点数 float, 才能进行后面的 `b/0.5`, 因为得到的要是一个小数. 还有很多其他的原因和详细说明 (比如 Python 对内存的调用) 在这里能够找到: &a href=&/?target=https%3A//jakevdp.github.io/blog//why-python-is-slow/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Why Python is Slow: Looking Under the Hood&i class=&icon-external&&&/i&&/a&&/p&&p&提到 Numpy, 它就是一个 Python 的救星. 能把简单好用的 Python 和高性能的 C 语言合并在一起. 当你调用 Numpy 功能的时候, 他其实调用了很多 C 语言而不是纯 Python. 这就是为什么大家都爱用 Numpy 的原因.&/p&&p&&br&&/p&&h2&创建 Numpy Array 的结构&/h2&&p&其实 Numpy 就是 C 的逻辑, 创建存储容器 &Array& 的时候是寻找内存上的一连串区域来存放, 而 Python 存放的时候则是不连续的区域, 这使得 Python 在索引这个容器里的数据时不是那么有效率. Numpy 只需要再这块固定的连续区域前后走走就能不费吹灰之力拿到数据. 下图是来自 &a href=&/?target=https%3A//jakevdp.github.io/blog//why-python-is-slow/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Why Python is Slow: Looking Under the Hood&i class=&icon-external&&&/i&&/a&, 他很好的解释了这一切.&/p&&img src=&/v2-2cda20c24f07_b.png& data-rawwidth=&871& data-rawheight=&486& class=&origin_image zh-lightbox-thumb& width=&871& data-original=&/v2-2cda20c24f07_r.png&&&p&&br&&/p&&p&在运用 Numpy 的时候, 我们通常不是用一个一维 Array 来存放数据, 而是用二维或者三维的块来存放 (说出了学机器学习的朋友们的心声~). &/p&&img src=&/v2-754a394fe70bc13b26c88b1aff6bccd2_b.png& data-rawwidth=&300& data-rawheight=&168& class=&content_image& width=&300&&&p&因为 Numpy 快速的矩阵相乘运算, 能将乘法运算分配到计算机中的多个核, 让运算并行. 这年头, 我们什么都想多线程/多进程 (再次说出了机器学习同学们的心声~). 这也是 Numpy 为什么受人喜欢的一个原因. 这种并行运算大大加速了运算速度. &/p&&p&那么对于这种天天要用到的2D/3D Array, 我们通常都不会想着他是怎么来的. 因为按照我们正常人的想法, 这矩阵就是矩阵, 没什么深度的东西呀. 不过这可不然! 要不然我也不会写这篇分享了. &b&重点来了, 不管是1D/2D/3D 的 Array, 从根本上, 它都是一个 1D array!&/b&&/p&&p&&br&&/p&&img src=&/v2-bb7cfb0a9b7d8bde_b.png& data-rawwidth=&737& data-rawheight=&299& class=&origin_image zh-lightbox-thumb& width=&737& data-original=&/v2-bb7cfb0a9b7d8bde_r.png&&&p&&br&&/p&&p&&a href=&/?target=http%3A//ipython-books.github.io/featured-01/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这篇 Blog&i class=&icon-external&&&/i&&/a&的图显示. 在我们看来的 2D Array, 如果追溯到计算机内存里, 它其实是储存在一个连续空间上的. &b&而对于这个连续空间, 我们如果创建 Array 的方式不同, 在这个连续空间上的排列顺序也有不同. 这将影响之后所有的事情! 我们后面会用 Python 进行运算时间测试. &/b&&/p&&p&在 Numpy 中, 创建 2D Array 的默认方式是 &C-type& 以 row 为主在内存中排列, 而如果是 &Fortran& 的方式创建的, 就是以 column 为主在内存中排列. &/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&col_major&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&zeros&/span&&span class=&p&&((&/span&&span class=&mi&&10&/span&&span class=&p&&,&/span&&span class=&mi&&10&/span&&span class=&p&&),&/span& &span class=&n&&order&/span&&span class=&o&&=&/span&&span class=&s1&&'C'&/span&&span class=&p&&)&/span&
&span class=&c1&&# C-type&/span&
&span class=&n&&row_major&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&zeros&/span&&span class=&p&&((&/span&&span class=&mi&&10&/span&&span class=&p&&,&/span&&span class=&mi&&10&/span&&span class=&p&&),&/span& &span class=&n&&order&/span&&span class=&o&&=&/span&&span class=&s1&&'F'&/span&&span class=&p&&)&/span&
&span class=&c1&&# Fortran&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&在 axis 上的动作&/h2&&p&当你的计算中涉及合并矩阵, 不同形式的矩阵创建方式会给你不同的时间效果. 因为&b&在 Numpy 中的矩阵合并等, 都是发生在一维空间里, ! 不是我们想象的二维空间中! &/b&&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&zeros&/span&&span class=&p&&((&/span&&span class=&mi&&200&/span&&span class=&p&&,&/span& &span class=&mi&&200&/span&&span class=&p&&),&/span& &span class=&n&&order&/span&&span class=&o&&=&/span&&span class=&s1&&'C'&/span&&span class=&p&&)&/span&
&span class=&n&&b&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&zeros&/span&&span class=&p&&((&/span&&span class=&mi&&200&/span&&span class=&p&&,&/span& &span class=&mi&&200&/span&&span class=&p&&),&/span& &span class=&n&&order&/span&&span class=&o&&=&/span&&span class=&s1&&'F'&/span&&span class=&p&&)&/span&
&span class=&n&&N&/span& &span class=&o&&=&/span& &span class=&mi&&9999&/span&
&span class=&k&&def&/span& &span class=&nf&&f1&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&concatenate&/span&&span class=&p&&((&/span&&span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&n&&a&/span&&span class=&p&&),&/span& &span class=&n&&axis&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&f2&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&concatenate&/span&&span class=&p&&((&/span&&span class=&n&&b&/span&&span class=&p&&,&/span& &span class=&n&&b&/span&&span class=&p&&),&/span& &span class=&n&&axis&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&n&&t0&/span& &span class=&o&&=&/span& &span class=&n&&time&/span&&span class=&o&&.&/span&&span class=&n&&time&/span&&span class=&p&&()&/span&
&span class=&n&&f1&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&)&/span&
&span class=&n&&t1&/span& &span class=&o&&=&/span& &span class=&n&&time&/span&&span class=&o&&.&/span&&span class=&n&&time&/span&&span class=&p&&()&/span&
&span class=&n&&f2&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&)&/span&
&span class=&n&&t2&/span& &span class=&o&&=&/span& &span class=&n&&time&/span&&span class=&o&&.&/span&&span class=&n&&time&/span&&span class=&p&&()&/span&
&span class=&k&&print&/span&&span class=&p&&((&/span&&span class=&n&&t1&/span&&span class=&o&&-&/span&&span class=&n&&t0&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&)&/span&
&span class=&c1&&# 0.000040&/span&
&span class=&k&&print&/span&&span class=&p&&((&/span&&span class=&n&&t2&/span&&span class=&o&&-&/span&&span class=&n&&t1&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&)&/span&
&span class=&c1&&# 0.000070&/span&
&/code&&/pre&&/div&&p&从上面的那张图, 可以想到, row 为主的存储方式, 如果在 row 的方向上合并矩阵, 将会更快. 因为只要我们将思维放在 1D array 那, 直接再加一个 row 放在1D array 后面就好了, 所以在上面的测试中, f1 速度要更快. 但是在以 column 为主的系统中, 往 1D array 后面加 row 的规则变复杂了, 消耗的时间也变长. 如果以 axis=1 的方式合并, &F& 方式的 f2 将会比 &C& 方式的 f1 更好.&/p&&p&还有一个要提的事情, 为了图方便, 有时候我会直接使用 `np.stack` 来代替 `np.concatenate`, 因为这样可以少写一点代码, 不过使用上面的形式, 通过上面的测试发现是这样. 所以之后为了速度, 我推荐还是尽量使用 `np.concatenate`.&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&vstack&/span&&span class=&p&&((&/span&&span class=&n&&a&/span&&span class=&p&&,&/span&&span class=&n&&a&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.000063&/span&
&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&concatenate&/span&&span class=&p&&((&/span&&span class=&n&&a&/span&&span class=&p&&,&/span&&span class=&n&&a&/span&&span class=&p&&),&/span& &span class=&n&&axis&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&c1&&# 0.000040&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&或者有时候在某个 axis 上进行操作, 比如对上面用 &C-type& 创建的 a 矩阵选点:&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&indices&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&random&/span&&span class=&o&&.&/span&&span class=&n&&randint&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&mi&&100&/span&&span class=&p&&,&/span& &span class=&n&&size&/span&&span class=&o&&=&/span&&span class=&mi&&10&/span&&span class=&p&&,&/span& &span class=&n&&dtype&/span&&span class=&o&&=&/span&&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&int32&/span&&span class=&p&&)&/span&
&span class=&n&&a&/span&&span class=&p&&[&/span&&span class=&n&&indices&/span&&span class=&p&&,&/span& &span class=&p&&:]&/span&
&span class=&c1&&# 0.000003&/span&
&span class=&n&&a&/span&&span class=&p&&[:,&/span& &span class=&n&&indices&/span&&span class=&p&&]&/span&
&span class=&c1&&# 0.000006&/span&
&/code&&/pre&&/div&&p&因为 a 是用 row 为主的形式储存, 所以在 row 上面选数据要比在 column 上选快很多! 对于其他的 axis 的操作, 结果也类似. 所以你现在懂了吧, 看自己要在哪个 axis 上动的手脚多, 然后再创建合适于自己的矩阵形式 (&C-type&/&Fortran&).&/p&&p&&br&&/p&&h2&copy慢 view快&/h2&&p&在 Numpy 中, 有两个很重要的概念, copy 和 view. copy 顾名思义, 会将数据 copy 出来存放在内存中另一个地方, 而 view 则是不 copy 数据, 直接取源数据的索引部分. 下图来自 &a href=&/?target=https%3A//www.dataquest.io/blog/settingwithcopywarning/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Understanding SettingwithCopyWarning in pandas&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&img src=&/v2-c14d4bb376e4b8f93df7e03d95c6fa00_b.png& data-rawwidth=&958& data-rawheight=&472& class=&origin_image zh-lightbox-thumb& width=&958& data-original=&/v2-c14d4bb376e4b8f93df7e03d95c6fa00_r.png&&&p&上面说的是什么意思呢? 我们直接看代码.&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&arange&/span&&span class=&p&&(&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span& &span class=&mi&&7&/span&&span class=&p&&)&/span&&span class=&o&&.&/span&&span class=&n&&reshape&/span&&span class=&p&&((&/span&&span class=&mi&&3&/span&&span class=&p&&,&/span&&span class=&mi&&2&/span&&span class=&p&&))&/span&
&span class=&n&&a_view&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[:&/span&&span class=&mi&&2&/span&&span class=&p&&]&/span&
&span class=&n&&a_copy&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[:&/span&&span class=&mi&&2&/span&&span class=&p&&]&/span&&span class=&o&&.&/span&&span class=&n&&copy&/span&&span class=&p&&()&/span&
&span class=&n&&a_copy&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span&&span class=&mi&&1&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&)&/span&
&span class=&sd&&&&&&/span&
&span class=&sd&&[[1 2]&/span&
&span class=&sd&& [3 4]&/span&
&span class=&sd&& [5 6]]&/span&
&span class=&sd&&&&&&/span&
&span class=&n&&a_view&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span&&span class=&mi&&1&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&)&/span&
&span class=&sd&&&&&&/span&
&span class=&sd&&[[1 2]&/span&
&span class=&sd&& [3 0]&/span&
&span class=&sd&& [5 6]]&/span&
&span class=&sd&&&&&&/span&
&/code&&/pre&&/div&&p&简单说, a_view 的东西全部都是 a 的东西, 动 a_view 的任何地方, a 都会被动到, 因为他们在内存中的位置是一模一样的, 本质上就是自己. 而 a_copy 则是将 a copy 了一份, 然后把 a_copy 放在内存中的另外的地方, 这样改变 a_copy, a 是不会被改变的.&/p&&p&那为什么要提这点呢? &b&因为 view 不会复制东西, 速度快! &/b&我们来测试一下速度. 下面的例子中 `a*=2` 就是将这个 view 给赋值了, 和 `a[:] *= 2` 一个意思, 从头到尾没有创建新的东西. 而 `b = 2*b` 中, 我们将 b 赋值给另外一个新建的 b. &/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&zeros&/span&&span class=&p&&((&/span&&span class=&mi&&1000&/span&&span class=&p&&,&/span& &span class=&mi&&1000&/span&&span class=&p&&))&/span&
&span class=&n&&b&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&zeros&/span&&span class=&p&&((&/span&&span class=&mi&&1000&/span&&span class=&p&&,&/span& &span class=&mi&&1000&/span&&span class=&p&&))&/span&
&span class=&n&&N&/span& &span class=&o&&=&/span& &span class=&mi&&9999&/span&
&span class=&k&&def&/span& &span class=&nf&&f1&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&a&/span& &span class=&o&&*=&/span& &span class=&mi&&2&/span&
&span class=&c1&&# same as a[:] *= 2&/span&
&span class=&k&&def&/span& &span class=&nf&&f2&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&b&/span& &span class=&o&&=&/span& &span class=&mi&&2&/span&&span class=&o&&*&/span&&span class=&n&&b&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t1&/span&&span class=&o&&-&/span&&span class=&n&&t0&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# f1: 0.000837&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t2&/span&&span class=&o&&-&/span&&span class=&n&&t1&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# f2: 0.001346&/span&
&/code&&/pre&&/div&&p&对于 view 还有一点要提, 你是不是偶尔有时候要把一个矩阵展平, 用到 `np.flatten()` 或者 `np.ravel()`. 他俩是不同的! ravel 返回的是一个 view (谢谢评论中 &a class=&member_mention& href=&/people/24fd3dafa3& data-hash=&24fd3dafa3& data-hovercard=&p$b$24fd3dafa3&&@非易&/a& 的提醒, &a href=&/?target=https%3A//docs.scipy.org/doc/numpy/reference/generated/numpy.ravel.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&官方说&i class=&icon-external&&&/i&&/a&如果用 ravel, 需要 copy 的时候才会被 copy , 我想这个时候可能是把 ravel 里面 order 转换的时候, 如 'C-type' -& 'Fortran'), 而 flatten 返回的总是一个 copy. 现在你知道谁在拖你的后腿了吧! 下面的测试证明, 相比于 flatten, ravel 是神速.&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&k&&def&/span& &span class=&nf&&f1&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&a&/span&&span class=&o&&.&/span&&span class=&n&&flatten&/span&&span class=&p&&()&/span&
&span class=&k&&def&/span& &span class=&nf&&f2&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&b&/span&&span class=&o&&.&/span&&span class=&n&&ravel&/span&&span class=&p&&()&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t1&/span&&span class=&o&&-&/span&&span class=&n&&t0&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.001059&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t2&/span&&span class=&o&&-&/span&&span class=&n&&t1&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.000000&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&选择数据&/h2&&p&选择数据的时候, 我们常会用到 view 或者 copy 的形式. 我们知道了, 如果能用到 view 的, 我们就尽量用 view, 避免 copy 数据. 那什么时候会是 view 呢? 下面举例的都是 view 的方式:&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a_view1&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&:&/span&&span class=&mi&&2&/span&&span class=&p&&,&/span& &span class=&mi&&3&/span&&span class=&p&&:&/span&&span class=&mi&&6&/span&&span class=&p&&]&/span&
&span class=&c1&&# 切片 slice&/span&
&span class=&n&&a_view2&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[:&/span&&span class=&mi&&100&/span&&span class=&p&&]&/span&
&span class=&c1&&# 同上&/span&
&span class=&n&&a_view3&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[::&/span&&span class=&mi&&2&/span&&span class=&p&&]&/span&
&span class=&c1&&# 跳步&/span&
&span class=&n&&a_view4&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&o&&.&/span&&span class=&n&&ravel&/span&&span class=&p&&()&/span&
&span class=&c1&&# 上面提到了&/span&
&span class=&o&&...&/span&
&span class=&c1&&# 我只能想到这些, 如果还有请大家在评论里提出&/span&
&/code&&/pre&&/div&&p&那哪些操作我们又会变成 copy 呢?&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a_copy1&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[[&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span&&span class=&mi&&4&/span&&span class=&p&&,&/span&&span class=&mi&&6&/span&&span class=&p&&],&/span& &span class=&p&&[&/span&&span class=&mi&&2&/span&&span class=&p&&,&/span&&span class=&mi&&4&/span&&span class=&p&&,&/span&&span class=&mi&&6&/span&&span class=&p&&]]&/span&
&span class=&c1&&# 用 index 选&/span&
&span class=&n&&a_copy2&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[[&/span&&span class=&bp&&True&/span&&span class=&p&&,&/span& &span class=&bp&&True&/span&&span class=&p&&],&/span& &span class=&p&&[&/span&&span class=&bp&&False&/span&&span class=&p&&,&/span& &span class=&bp&&True&/span&&span class=&p&&]]&/span&
&span class=&c1&&# 用 mask&/span&
&span class=&n&&a_copy3&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[[&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span&&span class=&mi&&2&/span&&span class=&p&&],&/span& &span class=&p&&:]&/span&
&span class=&c1&&# 虽然 1,2 的确连在一起了, 但是他们确实是 copy&/span&
&span class=&n&&a_copy4&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[&/span&&span class=&n&&a&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&,:]&/span& &span class=&o&&!=&/span& &span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&p&&:]&/span&
&span class=&c1&&# fancy indexing&/span&
&span class=&n&&a_copy5&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[&/span&&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&isnan&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&),&/span& &span class=&p&&:]&/span&
&span class=&c1&&# fancy indexing&/span&
&span class=&o&&...&/span&
&span class=&c1&&# 我只能想到这些, 如果还有请大家在评论里提出&/span&
&/code&&/pre&&/div&&p&Numpy 给了我们很多很自由的方式选择数据, 这些虽然都很方便, 但是如果你可以尽量避免这些操作, 你的速度可以飞起来.&/p&&p&在上面提到的 &a href=&/?target=http%3A//ipython-books.github.io/featured-01/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&blog&i class=&icon-external&&&/i&&/a& 里面, 他提到了, 如果你还是喜欢这种 fancy indexing 的形式, 我们也是可以对它加点速的. 那个 blog 中指出了两种方法&/p&&p&&b&1. 使用 `np.take()`, 替代用 index 选数据的方法. &/b&&/p&&p&上面提到了如果用index 来选数据, 像 `a_copy1 = a[[1,4,6], [2,4,6]]`, 用 take 在大部分情况中会比这样的 `a_copy1` 要快.&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&random&/span&&span class=&o&&.&/span&&span class=&n&&rand&/span&&span class=&p&&(&/span&&span class=&mi&&1000000&/span&&span class=&p&&,&/span& &span class=&mi&&10&/span&&span class=&p&&)&/span&
&span class=&n&&N&/span& &span class=&o&&=&/span& &span class=&mi&&99&/span&
&span class=&n&&indices&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&random&/span&&span class=&o&&.&/span&&span class=&n&&randint&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&mi&&1000000&/span&&span class=&p&&,&/span& &span class=&n&&size&/span&&span class=&o&&=&/span&&span class=&mi&&10000&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&f1&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&_&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&take&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&n&&indices&/span&&span class=&p&&,&/span& &span class=&n&&axis&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&f2&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&_&/span& &span class=&o&&=&/span& &span class=&n&&b&/span&&span class=&p&&[&/span&&span class=&n&&indices&/span&&span class=&p&&]&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t1&/span&&span class=&o&&-&/span&&span class=&n&&t0&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.000393&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t2&/span&&span class=&o&&-&/span&&span class=&n&&t1&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.000569&/span&
&/code&&/pre&&/div&&p&&b&2. 使用 `np.compress()`, 替代用 mask 选数据的方法. &/b&&/p&&p&上面的 `a_copy2 = a[[True, True], [False, True]]` 这种就是用 TRUE, FALSE 来选择数据的. 测试如下:&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&mask&/span& &span class=&o&&=&/span& &span class=&n&&a&/span&&span class=&p&&[:,&/span& &span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&&&/span& &span class=&mf&&0.5&/span&
&span class=&k&&def&/span& &span class=&nf&&f1&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&_&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&compress&/span&&span class=&p&&(&/span&&span class=&n&&mask&/span&&span class=&p&&,&/span& &span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&n&&axis&/span&&span class=&o&&=&/span&&span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&k&&def&/span& &span class=&nf&&f2&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&_&/span& &span class=&o&&=&/span& &span class=&n&&b&/span&&span class=&p&&[&/span&&span class=&n&&mask&/span&&span class=&p&&]&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t1&/span&&span class=&o&&-&/span&&span class=&n&&t0&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.028109&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t2&/span&&span class=&o&&-&/span&&span class=&n&&t1&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.031013&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&非常有用的 out 参数&/h2&&p&不深入了解 numpy 的朋友, 应该会直接忽略很多功能中的这个 out 参数 (之前我从来没用过). 不过当我深入了解了以后, 发现他非常有用! 比如下面两个其实在功能上是没差的, 不过运算时间上有差, 我觉得可能是 `a=a+1` 要先转换成 `np.add()` 这种形式再运算, 所以前者要用更久一点的时间.&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&a&/span& &span class=&o&&+&/span& &span class=&mi&&1&/span&
&span class=&c1&&# 0.035230&/span&
&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&mi&&1&/span&&span class=&p&&)&/span&
&span class=&c1&&# 0.032738&/span&
&/code&&/pre&&/div&&p&如果是上面那样, 我们就会触发之前提到的 copy 原则, 这两个被赋值的 a, 都是原来 a 的一个 copy, 并不是 a 的 view. 但是&b&在功能里面有一个 out 参数, 让我们不必要重新创建一个 a. 所以下面两个是一样的功能, 都不会创建另一个 copy. &/b&不过可能是上面提到的那个原因, 这里的运算时间也有差.&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a&/span& &span class=&o&&+=&/span& &span class=&mi&&1&/span&
&span class=&c1&&# 0.011219&/span&
&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&add&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&mi&&1&/span&&span class=&p&&,&/span& &span class=&n&&out&/span&&span class=&o&&=&/span&&span class=&n&&a&/span&&span class=&p&&)&/span&
&span class=&c1&&# 0.008843&/span&
&/code&&/pre&&/div&&p&带有 out 的 numpy 功能都在这里: &a href=&/?target=https%3A//docs.scipy.org/doc/numpy/reference/ufuncs.html%23available-ufuncs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Universal functions&i class=&icon-external&&&/i&&/a&. 所以只要是已经存在了一个 placeholder (比如 a), 我们就没有必要去再创建一个, 用 out 方便又有效.&/p&&p&&br&&/p&&p&&br&&/p&&h2&给数据一个名字&/h2&&p&我喜欢用 pandas, 因为 pandas 能让你给数据命名, 用名字来做 index. 在数据类型很多的时候, 名字总是比 index 好记太多了, 也好用太多了. 但是 pandas 的确比 numpy 慢. 好在我们还是有途径可以实现用名字来索引. 这就是 structured array. 下面 a/b 的结构是一样的, 只是一个是 numpy 一个是 pandas.&/p&&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&a&/span& &span class=&o&&=&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&zeros&/span&&span class=&p&&(&/span&&span class=&mi&&3&/span&&span class=&p&&,&/span& &span class=&n&&dtype&/span&&span class=&o&&=&/span&&span class=&p&&[(&/span&&span class=&s1&&'foo'&/span&&span class=&p&&,&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&int32&/span&&span class=&p&&),&/span& &span class=&p&&(&/span&&span class=&s1&&'bar'&/span&&span class=&p&&,&/span& &span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&float16&/span&&span class=&p&&)])&/span&
&span class=&n&&b&/span& &span class=&o&&=&/span& &span class=&n&&pd&/span&&span class=&o&&.&/span&&span class=&n&&DataFrame&/span&&span class=&p&&(&/span&&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&zeros&/span&&span class=&p&&((&/span&&span class=&mi&&3&/span&&span class=&p&&,&/span& &span class=&mi&&2&/span&&span class=&p&&),&/span& &span class=&n&&dtype&/span&&span class=&o&&=&/span&&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&int32&/span&&span class=&p&&),&/span& &span class=&n&&columns&/span&&span class=&o&&=&/span&&span class=&p&&[&/span&&span class=&s1&&'foo'&/span&&span class=&p&&,&/span& &span class=&s1&&'bar'&/span&&span class=&p&&])&/span&
&span class=&n&&b&/span&&span class=&p&&[&/span&&span class=&s1&&'bar'&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&n&&b&/span&&span class=&p&&[&/span&&span class=&s1&&'bar'&/span&&span class=&p&&]&/span&&span class=&o&&.&/span&&span class=&n&&astype&/span&&span class=&p&&(&/span&&span class=&n&&np&/span&&span class=&o&&.&/span&&span class=&n&&float16&/span&&span class=&p&&)&/span&
&span class=&sd&&&&&
&span class=&sd&&# a&/span&
&span class=&sd&&array([(0,
0.)],&/span&
&span class=&sd&&
dtype=[('foo', '&i4'), ('bar', '&f2')])&/span&
&span class=&sd&&# b&/span&
&span class=&sd&&
bar&/span&
&span class=&sd&&0
0.0&/span&
&span class=&sd&&1
0.0&/span&
&span class=&sd&&2
0.0&/span&
&span class=&sd&&&&&&/span&
&span class=&k&&def&/span& &span class=&nf&&f1&/span&&span class=&p&&(&/span&&span class=&n&&a&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&a&/span&&span class=&p&&[&/span&&span class=&s1&&'bar'&/span&&span class=&p&&]&/span& &span class=&o&&*=&/span& &span class=&n&&a&/span&&span class=&p&&[&/span&&span class=&s1&&'foo'&/span&&span class=&p&&]&/span&
&span class=&k&&def&/span& &span class=&nf&&f2&/span&&span class=&p&&(&/span&&span class=&n&&b&/span&&span class=&p&&):&/span&
&span class=&k&&for&/span& &span class=&n&&_&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&n&&N&/span&&span class=&p&&):&/span&
&span class=&n&&b&/span&&span class=&p&&[&/span&&span class=&s1&&'bar'&/span&&span class=&p&&]&/span& &span class=&o&&*=&/span& &span class=&n&&b&/span&&span class=&p&&[&/span&&span class=&s1&&'foo'&/span&&span class=&p&&]&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t1&/span&&span class=&o&&-&/span&&span class=&n&&t0&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.000003&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'&/span&&span class=&si&&%f&/span&&span class=&s1&&'&/span& &span class=&o&&%&/span& &span class=&p&&((&/span&&span class=&n&&t2&/span&&span class=&o&&-&/span&&span class=&n&&t1&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&n&&N&/span&&span class=&p&&))&/span&
&span class=&c1&&# 0.000508&/span&
&/code&&/pre&&/div&&p&可以看出来, numpy 明显比 pandas 快很多. 如果需要使用到不同数据形式, numpy 也是可以胜任的, 并且在还保持了快速的计算速度. 至于 pandas 为什么比 numpy 慢, 因为 pandas data 里面还有很多七七八八的数据, 记录着这个 data 的种种其他的特征.
这里还有更全面的对比: &a href=&/?target=http%3A///blog/numpy-vs-pandas-comparison.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Numpy Vs Pandas Performance Comparison&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&&b&&i&如果大家还有其他的小技巧或者是速度大比拼, 欢迎在下面讨论. (一切为了速度~)&/i&&/b&&/p&&p&最后插个小广告, 如果你对机器学习感兴趣, 这里有很多厉害的短片形式机器学习方法介绍和很多机器学习的 Python 实践教程, 让你可以用业余时间秒懂机器学习: &a href=&/?target=https%3A//morvanzhou.github.io/tutorials/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&莫烦Python 教程&i class=&icon-external&&&/i&&/a&&/p&
最近在写代码, 编一个 Python 模拟器, 做 simulation, 好不容易用传说中 Python 里速度最快的计算模块 "Numpy" 的写好了, 结果运行起来, 出奇的慢! 因为一次simulation要一个小时, 要不停测试, 所以自己受不了了.. 首先, 我的脑海中的问题, 渐渐浮现出来.我…
&figure&&img src=&/50/v2-6dd142eeb9cb23b84d10f11f4b0d6bdd_b.jpg& data-rawwidth=&640& data-rawheight=&480& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-6dd142eeb9cb23b84d10f11f4b0d6bdd_r.jpg&&&/figure&&blockquote&允中 编译整理&br&量子位 出品 | 公众号 QbitAI&/blockquote&&p&DMLC项目发起人陈天奇今天早间宣布推出TVM。&/p&&p&所谓TVM,按照正式说法:就是一种将深度学习工作负载部署到硬件的端到端IR(中间表示)堆栈。换一种说法,可以表述为一种把深度学习模型分发到各种硬件设备上的、端到端的解决方案。&/p&&p&陈天奇在微博上表示,TVM和之前发布的模块化深度学习系统NNVM一起,“组成深度学习到各种硬件的完整优化工具链”。&/p&&p&同在DMLC小组的刘洪亮(phunter_lau)进一步在微博上解释了这个工作的意义:“TVM可以把模型部署到不同硬件,比如群众常问的能不能用AMD的GPU,用FPGA怎么搞,TVM提供这个中间层有效解决这个问题”。&/p&&img src=&/50/v2-6dd142eeb9cb23b84d10f11f4b0d6bdd_b.jpg& data-rawwidth=&640& data-rawheight=&480& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-6dd142eeb9cb23b84d10f11f4b0d6bdd_r.jpg&&&p&&b&△&/b& 陈天奇,华盛顿大学计算机系博士生,此前毕业于上海交通大学ACM班。XGBoost、cxxnet等著名机器学习工具的作者,MXNet的主要贡献者之一。&/p&&p&随后陈天奇也补充说:&/p&&p&除了比较明显的多硬件支持,更重要的是支持比较方便的自动调优和轻量级部署。比如我们有同学可以在一些workload可以达到和cudnn差不多的效果,而且同样的东西可以迁移到其它非cuda设备。&/p&&p&非常建议大家尝试一下。&/p&&p&而在reddit上,刘洪亮形象的比喻称:以后可以让树莓派来找猫~&/p&&img src=&/50/v2-9788da36abe25b77dd542_b.jpg& data-rawwidth=&640& data-rawheight=&275& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-9788da36abe25b77dd542_r.jpg&&&p&关于TVM的官方介绍,量子位尝试把主要内容编译如下。查看原文可以点击页面左下角“阅读原文”按钮。&/p&&p&作者:Tianqi Chen(project lead), Thierry Moreau(hardware stack), Ziheng Jiang(graph compilation), Haichen Shen(gpu optimization)&/p&&p&深度学习已经变得无处不在、不可或缺。&/p&&p&此次变革的推手之一,是可扩展的深度学习系统,例如TensorFlow、MXNet、Caffe以及PyTorch等。大多数现有系统只对部分服务器级GPU进行了优化,如果想部署到手机、物联网设备以及专用加速器(FPGA、ASIC)等平台,还有大量的工作要做。&/p&&p&随着深度学习框架和硬件后端数量的增加,我们提出一个统一的中间表示(IR)堆栈,用来弥合深度学习框架和硬件后端之间的距离。&/p&&img src=&/50/v2-e11e18ddf73b78f50f344e2a0dd53f92_b.jpg& data-rawwidth=&640& data-rawheight=&380& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-e11e18ddf73b78f50f344e2a0dd53f92_r.jpg&&&p&我们很高兴的宣布推出TVM来解决上述问题。TVM是一个全新的框架,可以:&/p&&ul&&li&为CPU、GPU和其他专用硬件,表示和优化常见的深度学习计算工作负载&/li&&li&自动转换计算图以最小化内存占用,优化数据布局和融合计算模式&/li&&li&提供端到端编译,从现有的前端框架到裸机硬件,直到浏览器可执行的javascript&/li&&/ul&&p&在TVM的帮助下,可以轻松在手机、嵌入式设备甚至浏览器上运行深度学习的工作负载,而不需要额外的工作。TVM还为许多硬件平台上的深度学习工作负载,提供统一的优化框架,包括依赖于新计算基元的专用加速器。&/p&&img src=&/50/v2-1a773b7bf5a0e_b.jpg& data-rawwidth=&640& data-rawheight=&296& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-1a773b7bf5a0e_r.jpg&&&p&我们采用了编译器界的共同理念,提供两个中间表示层,以有效地将高级深度学习算法降低到多种硬件后端。&/p&&p&在这次放出的版本中,开源的TVM软件包提供x86、ARM、OpenCL、Metal、CUDA和JavaScript的优化基元。我们正积极的致力于增加对专业硬件加速和Nvidia GEMM优化的Volta架构的支持。&/p&&h2&技术细节&/h2&&p&TVM堆栈的目标,是提供一个可重复使用的工具链,来将高级神经网络描述从深度学习框架前端,向下编译为多个硬件后端的低级机器代码。&/p&&p&以Apache MXNet作为前端案例,下面的代码演示了如何使用TVM将深度学习模型的高级描述编译为针对目标硬件定制的优化可执行模块。&/p&&img src=&/50/v2-4f93eef3c704c_b.jpg& data-rawwidth=&640& data-rawheight=&181& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-4f93eef3c704c_r.jpg&&&p&这件事的挑战在于支持多个硬件后端,同时将计算、内存和能量足迹保持在最低水平。我们借鉴了编译器界的智慧,构建了两级中间层:其中一层是NNVM(用于任务调度和内存管理的高级中间表示),另一层是TVM(用于优化计算内核的富有表现力的低级中间表示)&/p&&p&堆栈的第一级是基于计算图的表示。计算图是一个有向无环图,用节点表示计算,用箭头表示数据流关系。大多数现有深度学习框架都采用这种方法,包括TVM堆栈中的NNVM图表示,TensorFlow XLA以及英特尔的Ngraph。&/p&&img src=&/50/v2-845fca671ba70fdff5836bd_b.jpg& data-rawwidth=&640& data-rawheight=&173& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-845fca671ba70fdff5836bd_r.jpg&&&p&图优化框架可以支持很多强大的优化。例如,我们提供了一个次线性内存优化功能,允许用户在单个GPU上训练1000层的ImageNet ResNet。&/p&&p&&br&&/p&&img src=&/50/v2-de91d3bd3cdf51f4a276_b.jpg& data-rawwidth=&640& data-rawheight=&323& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-de91d3bd3cdf51f4a276_r.jpg&&&p&然而,我们发现仅基于IR的计算图不足以解决支持不同硬件后端的挑战。因为单独一个图形运算符,例如卷积或矩阵乘法能以非常不同的方式映射和优化在不同的硬件后端。这些特定硬件优化在内存布局、并行线程模式、缓存访问模式和硬件基元的选择方面,可能会发生巨大的变化。我们希望能以通用方式对此进行明确表达。&/p&&p&我们建立了一个低级表示来解决这个问题。这个表示基于索引公式,而且支持重复计算。&/p&&img src=&/50/v2-648bbef93017fdb7a00de_b.jpg& data-rawwidth=&640& data-rawheight=&214& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-648bbef93017fdb7a00de_r.jpg&&&p&低级别IR采用了现有的图像处理语言(例如Halide或darkroom)的原理来制定一种表现力很强的深度学习DSL。TVM在循环变换工具(例如loopy等)的启发下构建了图优化。我们也从MXNet、TensorFlow、Theano等深度学习框架的数据流描述语言中获得灵感。然后在调度阶段对TVM中描述的算法进行处理,以应用针对目标硬件后端订制的转换。&/p&&img src=&/50/v2-7e5d6fda569e3d_b.jpg& data-rawwidth=&640& data-rawheight=&263& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-7e5d6fda569e3d_r.jpg&&&p&TVM包括CPU优化框架中常见的标准转换基元。更重要的是,TVM集成了针对GPU的新优化基元,包括利用线程协作模式、数据布局变换和强大的计算基元。将TVM和NNVM结合使用,可以用多种方式优化软件堆栈中的深度学习工作负载,进一步实现计算图级和运算符级的优化。&/p&&p&多语言和平台支持&/p&&p&TVM的优势之一,就是对多个平台和语言提供了丰富的支持。这由两个部分组成。一是编译器堆栈,其中包括完整的优化库,以产生优化过的机器代码;二是轻量级的运行环境,提供了在不同平台上部署编译模块所需的可移植性。&/p&&img src=&/50/v2-88727be8ebc3fc7dbaf97d7c_b.jpg& data-rawwidth=&640& data-rawheight=&243& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-88727be8ebc3fc7dbaf97d7c_r.jpg&&&p&TVM目前支持嵌入式编译器堆栈的Python和C++接口。我们在设计框架时最大程度的实现了重复利用,以便编译器堆栈的改进可以在Python和C++组建之间互换使用。&/p&&p&我们还提供了一个轻量级的运行环境,可以让TVM用JavaScript、Java、Python、C++等编译过的代码,运行在Android、iOS、树莓派和网页浏览器等平台上。&/p&&p&远程部署和执行&/p&&img src=&/50/v2-0d41edf1b3d887bad898c95dcac6322a_b.jpg& data-rawwidth=&640& data-rawheight=&242& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-0d41edf1b3d887bad898c95dcac6322a_r.jpg&&&p&通过轻量级的接口TVM RPC,可以在远程嵌入式

我要回帖

更多关于 ag亚游不让提款 的文章

 

随机推荐