首页 文章 精选 留言 我的

精选列表

搜索[教程],共9166篇文章
优秀的个人博客,低调大师

IntelliJ IDEA安装教程

​ 1. 下载阿里云Maven仓库服务器配置文件 由于IntelliJ IDEA的默认Maven仓库服务器是Apache平台的,下载文件时较慢,且容易在下载过程中丢失数据而导致文件损坏,所以,需要将Maven仓库服务器配置为国内的站点,例如阿里云或华为云等。 以配置阿里云Maven仓库服务器为例,先打开 http://doc.canglaoshi.org 网站,下载配置文件压缩包: ​ 将下载得到压缩包文件解压,将得到settings.xml文件: ​ 以上文件暂时放在任何位置即可,当安装完IntelliJ IDEA后再使用它。 2. 下载IntelliJ IDEA安装包 IntelliJ IDEA是目前主流的Java开发工具之一,甚至许多企业在招聘启示中明确要求开发人员掌握IntelliJ IDEA的使用!可以打开浏览器搜索intellij idea关键字,在搜索结果中找到其官方网站https://www.jetbrains.com/idea/并点击进入: ​ 点击主页的DOWNLOAD按钮以打开下载页面: ​ 在下载页面中,可以看到IntelliJ IDEA有Ultimate企业版(终极版)和Community社区版,如果需要开发Java企业级应用,需要下载Ultimate版,该版本是付费使用软件,有30天的免费试用时间。 直接下载的是最新版本,如需下载早期其它版本,点击左侧的Other Versions链接: ​ ​ 选择所需要的安装文件下载即可: ​ 3. 开始安装IntelliJ IDEA 找到下载的安装包文件并执行,即可打开安装向导,在第1个界面直接点击Next即可: ​ 在选择安装路径的界面,可以自行确定IntelliJ IDEA的安装目录,并点击Next到下一步: ​ 关于安装选项主要有: Create Desktop Shorcut:创建桌面快捷方式,可勾选中64-bit launcher,则安装完成后,会在桌面生成启动IntelliJ IDEA的快捷方式; Update PATH variable:更新PATH环境变量,如果勾选中该选项,则IntelliJ IDEA的安装目录会被配置到系统的PATH环境变量中,主要表现为在命令提示符窗口中,在任何位置都可以直接启动IntelliJ IDEA,其实具体作用并不明显,可以自由勾选; Update context menu:更新上下文菜单(右键菜单); Create Associations:创建文件类型关联,如果勾选对应的扩展名,则以后双击对应类型的文件时,会使用IntelliJ IDEA打开这些文件; Download and install 32-bit JetBrains Runtime:下载并安装应用于32位操作系统的JetBrains运行环境。 确认了安装选项后,继续点击Next到下一步: ​ 关于开始菜单的文件夹,保持默认即可: ​ 然后,等待安装完成即可: ​ 4. 准备使用IntellJ IDEA 双击桌面的IntelliJ IDEA快捷方式,即可启动IntelliJ IDEA,第1次运行时,会打开一些设置界面,首先是使用的许可协议,直接勾选表示“同意许可协议”即可: ​ 在Data Sharing界面,表示IntelliJ IDEA希望使用者能分享一些数据帮助其进行改进,且明确的表示了分享的数据将不包括个人信息及任何敏感数据,例如源代码、文件等。 点击Don't Send表示不会向IntelliJ IDEA分享任何数据,点击Send Anonymous Statistics表示将匿名发送,可根据自已实际情况进行选择: ​ IntelliJ IDEA的默认主题风格有Darcula的暗色风格和Light的亮色风格,可根据自己喜好进行选择: ​ IntelliJ IDEA默认就已经安装了许多插件,使得开发人员可以更快捷的进行开发,当前Default plugins界面显示的是已经安装的插件,可以点击对应的Customize自行定制,或点击对应的Disable All将其全部禁用,由于该界面中显示的插件大多是常规使用插件,且使用频率可能较高,如果尚且不了解各插件的作用,建议不作任何修改,直接点击右下角的Next: Featured plugins到下一步: ​ 在Download featured plugins界面显示的是高级插件,默认并没有安装,如果需要,可以点击对应的Install按钮,将下载并安装,如果尚且不了解各插件的作用,可以暂不安装(如果以后有使用需求,也可以在设置界面中安装),直接点击右下角的Start using IntelliJ IDEA以开始使用: ​ IntelliJ IDEA的Ultimate版是付费使用软件,如果已经购买,可以输入由卖家提供的激活资料: ​ 选中Evaluate for free表示“免费试用”,并点击Evaluate开始试用: ​ 5. 配置阿里云Maven仓库服务器 可以(非必要)在IntelliJ IDEA的主界面中点击Configure并选择Settings以打开设置: ​ 在设置界面中,在左侧依次展开Build, Execution, Deployment>Build Tools>Maven,在右侧可以看到默认的设置文件位置: ​ 将此前下载解压得到的settings.xml文件放在这个位置即可: ​ ​

优秀的个人博客,低调大师

Dart 入门教程

[TOC] 一、开篇 dart 语言具有如下特性 一切变量皆是对象,每个对象都是类的实例。int、double、函数、 null 等都是对象,所有对象都继承自 Object 类 dart 是强类型语言,但由于具备类型推导功能所以类型声明是可选的 dart 支持顶级函数、静态函数、实例函数,也允许在函数中嵌套函数,即局部函数。类似的,dart 也支持顶级变量、静态变量和实例变量 dart 没有关于 public、protected、private 的关键字。通过为变量标识符添加下划线前缀,表明该标识符对其库是私有的 .... 先来看个小例子 /** * 多行注释 */ void printString(String msg) { print("msg value: $msg"); } void main() { var msg = "H

优秀的个人博客,低调大师

Maven入门教程

GitHub仓库:Fundebug/maven-tutorial Maven简介 Maven是Java项目构建工具,可以用于管理Java依赖,还可以用于编译、打包以及发布Java项目,类似于JavaScript生态系统中的NPM。 Maven的命令行工具为mvn,其常用命令如下表所示: | 命令 | 说明 | | ----------- | -----------------------| | mvn compile | 编译Java源代码 | | mvn package | 打包Java项目 || mvn deploy | 将Java项目发布到Maven仓库 || mvn clean | 删除构建目录 | Maven的配置文件为pom.xml,这个文件有个很吓人的学术名字Project Object Model,但是怎么看它都只是个普通的配置文件,与NPM中的package.json没啥本质区别。 Maven的中央仓库为Maven Repository,这里可以找到各种Java依赖,例如我们Fundebug的异常监控插件fundebug-java与fundebug-spring。 安装Maven 在MacBook上使用brew安装很方便 brew install maven 我安装的是maven版本3.5.4 mvn -version Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00) Maven home: /usr/local/Cellar/maven/3.5.4/libexec Java version: 1.8.0_192, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/jre Default locale: zh_CN, platform encoding: UTF-8 OS name: "mac os x", version: "10.14.2", arch: "x86_64", family: "mac" 示例代码 本文示例代码都在GitHub仓库Fundebug/maven-tutorial。 使用tree命令可以查看项目的目录结构: tree -v . ├── pom.xml └── src └── main └── java └── com └── fundebug └── Hello.java pom.xml为Maven配置文件,位于项目的根目录。 Hello.java为Java源代码,位于src/main/java/com/fundebug目录中。根据Maven对目录结构的要求,Java源代码必须位于src/main/java目录。 Hello.java package com.fundebug; import org.json.JSONObject; public class Hello { public static void main(String[] args) { JSONObject tomJsonObj = new JSONObject(); tomJsonObj.put("name", "Fundebug"); tomJsonObj.put("url", "https://www.fundebug.com"); System.out.println(tomJsonObj.toString(4)); } } Hello.java非常简单,定义了一个JSON对象,然后把它打印出来了。 package定义的包名为com.fundebug,需要与所在的目录结构相吻合,因此Hello.java位于src/main/java/com/fundebug目录中,而不是src/main/java/目录中。 代码依赖于第三方模块json,因此需要在pom.xml配置dependency: <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20180813</version> </dependency> pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 坐标 --> <groupId>com.fundebug</groupId> <artifactId>hello</artifactId> <version>1.0</version> <!-- 依赖 --> <dependencies> <!-- https://mvnrepository.com/artifact/org.json/json --> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20180813</version> </dependency> </dependencies> </project> pom.xml中,<project></project>为最外层的标签;<modelVersion>4.0.0</modelVersion>定义了所使用的POM版本。这2个标签基本上是不变的。 groupId、artifactId与version一起则定义了模块的坐标(Coordinates),每个公共模块的坐标应该是唯一的: groupId:组织名称,通常是把域名反过来,例如com.fundebug artifactId:模块名称,例如fundebug-java version:模块版本,例如0.2.0 <dependencies></dependencies>定义了当前项目所依赖的模块: <dependencies> <!-- https://mvnrepository.com/artifact/org.json/json --> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20180813</version> </dependency> </dependencies> Maven可以根据<dependency></dependency>中定义的坐标,自动下载所依赖的模块。在MacBook上,Maven将下载的模块缓存在$HOME/.m2/目录。 使用mvn打包 执行mvn package命令,即可将源码打包为.jar文件: mvn package [INFO] Scanning for projects... [INFO] [INFO] -------------------------< com.fundebug:hello >------------------------- [INFO] Building hello 1.0 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /Users/fundebug/Desktop/maven-tutorial/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello --- [INFO] Changes detected - recompiling the module! [WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent! [INFO] Compiling 1 source file to /Users/fundebug/Desktop/maven-tutorial/target/classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello --- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /Users/fundebug/Desktop/maven-tutorial/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello --- [INFO] No sources to compile [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello --- [INFO] Building jar: /Users/fundebug/Desktop/maven-tutorial/target/hello-1.0.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.789 s [INFO] Finished at: 2019-01-05T15:23:02+08:00 [INFO] ------------------------------------------------------------------------ mvn package执行之后,项目中会新增一个tartget目录,编译的字节码文件位于target/classes目录,而jar包位于target/hello-1.0.jar: tree -v . ├── pom.xml ├── src │ └── main │ └── java │ └── com │ └── fundebug │ └── Hello.java └── target ├── classes │ └── com │ └── fundebug │ └── Hello.class ├── hello-1.0.jar 使用mvn运行 打包好的jar包,可以直接使用java命令运行时,注意需要指定所依赖的jar包。对于所依赖的jar包,Maven则会自动下载依赖,放在本地仓库中。在MacBook上,Maven本地仓库位于$HOME/.m2/目录。 java -cp target/hello-1.0.jar:$HOME/.m2/repository/org/json/json/20180813/json-20180813.jar com.fundebug.Hello { "name": "Fundebug", "url": "https://www.fundebug.com" } 也可以使用mvn exec:java命令执行,不需要指定依赖的jar包,更加方便: mvn exec:java -Dexec.mainClass="com.fundebug.Hello" [INFO] Scanning for projects... [INFO] [INFO] -------------------------< com.fundebug:hello >------------------------- [INFO] Building hello 1.0 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ hello --- { "name": "Fundebug", "url": "https://www.fundebug.com" } [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.837 s [INFO] Finished at: 2019-01-05T15:33:57+08:00 [INFO] ------------------------------------------------------------------------ 参考 Simple Maven Project Maven Dependency Management Java JSON Tutorial and Example: JSON-Java (org.json)

优秀的个人博客,低调大师

收藏 | Numpy详细教程

NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。 Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。 这个开源项目有很多贡献者。 Numpy基础 NumPy的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型、通过一个正整数元组索引的元素表格(通常是元素是数字)。在NumPy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。 例如,在3D空间一个点的坐标[1, 2, 3]是一个秩为1的数组,因为它只有一个轴。那个轴长度为3.又例如,在以下例子中,数组的秩为2(它有两个维度).第一个维度长度为2,第二个维度长度为3. [[ 1., 0., 0.], [ 0., 1., 2.]] NumPy的数组类被称作ndarray。通常被称作数组。注意numpy.array和标准Python库类array.array并不相同,后者只处理一维数组和提供少量功能。更多重要ndarray对象属性有: ndarray.ndim: 数组轴的个数,在python的世界中,轴的个数被称作秩 ndarray.shape:数组的维度。这是一个指示数组在每个维度上大小的整数元组。例如一个n排m列的矩阵,它的shape属性将是(2,3),这个元组的长度显然是秩,即维度或者ndim属性 ndarray.size 数组元素的总个数,等于shape属性中元组元素的乘积。 ndarray.dtype 一个用来描述数组中元素类型的对象,可以通过创造或指定dtype使用标准Python类型。另外NumPy提供它自己的数据类型。 ndarray.itemsize 数组中每个元素的字节大小。例如,一个元素类型为float64的数组itemsiz属性值为8(=64/8),又如,一个元素类型为complex32的数组item属性为4(=32/8). ndarray.data 包含实际数组元素的缓冲区,通常我们不需要使用这个属性,因为我们总是通过索引来使用数组中的元素。 例如: >>> from numpy import * >>> a = arange(15).reshape(3, 5) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> a.shape (3, 5) >>> a.ndim 2 >>> a.dtype.name 'int32' >>> a.itemsize 4 >>> a.size 15 >>> type(a) numpy.ndarray >>> b = array([6, 7, 8]) >>> b array([6, 7, 8]) >>> type(b) numpy.ndarray 创建数组 有好几种创建数组的方法。 例如,你可以使用 array函数从常规的Python列表和元组创造数组。所创建的数组类型由原序列中的元素类型推导而来。 >>> from numpy import * >>> a = array( [2,3,4] ) >>> a array([2, 3, 4]) >>> a.dtype dtype('int32') >>> b = array([1.2, 3.5, 5.1]) >>> b.dtype dtype('float64') 一个常见的错误包括用多个数值参数调用`array`而不是提供一个由数值组成的列表作为一个参数。 >>> a = array(1,2,3,4) # WRONG >>> a = array([1,2,3,4]) # RIGHT 数组将序列包含序列转化成二维的数组,序列包含序列包含序列转化成三维数组等等。 >>> b = array( [ (1.5,2,3), (4,5,6) ] ) >>> b array([[ 1.5, 2. , 3. ], [ 4. , 5. , 6. ]]) 数组类型可以在创建时显示指定 >>> c = array( [ [1,2], [3,4] ], dtype=complex ) >>> c array([[ 1.+0.j, 2.+0.j], [ 3.+0.j, 4.+0.j]]) 通常,数组的元素开始都是未知的,但是它的大小已知。因此,NumPy提供了一些使用占位符创建数组的函数。这最小化了扩展数组的需要和高昂的运算代价。 函数 function创建一个全是0的数组,函数 ones创建一个全1的数组,函数 empty创建一个内容随机并且依赖与内存状态的数组。默认创建的数组类型(dtype)都是float64。 >>> zeros( (3,4) ) array([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]]) >>> ones( (2,3,4), dtype=int16 ) # dtype can also be specified array([[[ 1, 1, 1, 1], [ 1, 1, 1, 1], [ 1, 1, 1, 1]], [[ 1, 1, 1, 1], [ 1, 1, 1, 1], [ 1, 1, 1, 1]]], dtype=int16) >>> empty( (2,3) ) array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260], [ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])为了创建一个数列,NumPy提供一个类似arange的函数返回数组而不是列表: >>> arange( 10, 30, 5 ) array([10, 15, 20, 25]) >>> arange( 0, 2, 0.3 ) # it accepts float arguments array([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8]) 当 arange使用浮点数参数时,由于有限的浮点数精度,通常无法预测获得的元素个数。因此,最好使用函数 linspace去接收我们想要的元素个数来代替用range来指定步长。 打印数组 当你打印一个数组,NumPy以类似嵌套列表的形式显示它,但是呈以下布局: 最后的轴从左到右打印 次后的轴从顶向下打印 剩下的轴从顶向下打印,每个切片通过一个空行与下一个隔开 一维数组被打印成行,二维数组成矩阵,三维数组成矩阵列表。 >>> a = arange(6) # 1d array >>> print a [0 1 2 3 4 5] >>> >>> b = arange(12).reshape(4,3) # 2d array >>> print b [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] >>> >>> c = arange(24).reshape(2,3,4) # 3d array >>> print c [[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [[12 13 14 15] [16 17 18 19] [20 21 22 23]]] 如果一个数组用来打印太大了,NumPy自动省略中间部分而只打印角落 >>> print arange(10000) [ 0 1 2 ..., 9997 9998 9999] >>> >>> print arange(10000).reshape(100,100) [[ 0 1 2 ..., 97 98 99] [ 100 101 102 ..., 197 198 199] [ 200 201 202 ..., 297 298 299] ..., [9700 9701 9702 ..., 9797 9798 9799] [9800 9801 9802 ..., 9897 9898 9899] [9900 9901 9902 ..., 9997 9998 9999]] 禁用NumPy的这种行为并强制打印整个数组,你可以设置 printoptions参数来更改打印选项。 >>> set_printoptions(threshold='nan') 基本运算 数组的算术运算是按元素的。新的数组被创建并且被结果填充。 >>> a = array( [20,30,40,50] ) >>> b = arange( 4 ) >>> b array([0, 1, 2, 3]) >>> c = a-b >>> c array([20, 29, 38, 47]) >>> b**2 array([0, 1, 4, 9]) >>> 10*sin(a) array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854]) >>> a<35 array([True, True, False, False], dtype=bool) 不像许多矩阵语言,NumPy中的乘法运算符*指示按元素计算,矩阵乘法可以使用dot函数或创建矩阵对象实现 >>> A = array( [[1,1], ... [0,1]] ) >>> B = array( [[2,0], ... [3,4]] ) >>> A*B # elementwise product array([[2, 0], [0, 4]]) >>> dot(A,B) # matrix product array([[5, 4], [3, 4]]) 有些操作符像 +=和 *=被用来更改已存在数组而不创建一个新的数组。 >>> a = ones((2,3), dtype=int) >>> b = random.random((2,3)) >>> a *= 3 >>> a array([[3, 3, 3], [3, 3, 3]]) >>> b += a >>> b array([[ 3.69092703, 3.8324276 , 3.0114541 ], [ 3.18679111, 3.3039349 , 3.37600289]]) >>> a += b # b is converted to integer type >>> a array([[6, 6, 6], [6, 6, 6]]) 当运算的是不同类型的数组时,结果数组和更普遍和精确的已知(这种行为叫做upcast)。 >>> a = ones(3, dtype=int32) >>> b = linspace(0,pi,3) >>> b.dtype.name 'float64' >>> c = a+b >>> c array([ 1. , 2.57079633, 4.14159265]) >>> c.dtype.name 'float64' >>> d = exp(c*1j) >>> d array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j, -0.54030231-0.84147098j]) >>> d.dtype.name 'complex128' 许多非数组运算,如计算数组所有元素之和,被作为ndarray类的方法实现 >>> a = random.random((2,3)) >>> a array([[ 0.6903007 , 0.39168346, 0.16524769], [ 0.48819875, 0.77188505, 0.94792155]]) >>> a.sum() 3.4552372100521485 >>> a.min() 0.16524768654743593 >>> a.max() 0.9479215542670073这些运算默认应用到数组好像它就是一个数字组成的列表,无关数组的形状。然而,指定 axis参数你可以吧运算应用到数组指定的轴上: >>> b = arange(12).reshape(3,4) >>> b array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> b.sum(axis=0) # sum of each column array([12, 15, 18, 21]) >>> >>> b.min(axis=1) # min of each row array([0, 4, 8]) >>> >>> b.cumsum(axis=1) # cumulative sum along each row array([[ 0, 1, 3, 6], [ 4, 9, 15, 22], [ 8, 17, 27, 38]]) 通用函数(ufunc) NumPy提供常见的数学函数如 sin, cos和 exp。在NumPy中,这些叫作“通用函数”(ufunc)。在NumPy里这些函数作用按数组的元素运算,产生一个数组作为输出. >>> B = arange(3) >>> B array([0, 1, 2]) >>> exp(B) array([ 1. , 2.71828183, 7.3890561 ]) >>> sqrt(B) array([ 0. , 1. , 1.41421356]) >>> C = array([2., -1., 4.]) >>> add(B, C) array([ 2., 0., 6.]) 索引,切片和迭代 一维数组可以被索引、切片和迭代,就像列表和其它Python序列。 >>> a = arange(10)**3 >>> a array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]) >>> a[2] 8 >>> a[2:5] array([ 8, 27, 64]) >>> a[:6:2] = -1000 # equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000 >>> a array([-1000, 1, -1000, 27, -1000, 125, 216, 343, 512, 729]) >>> a[ : :-1] # reversed a array([ 729, 512, 343, 216, 125, -1000, 27, -1000, 1, -1000]) >>> for i in a: ... print i**(1/3.), ... nan 1.0 nan 3.0 nan 5.0 6.0 7.0 8.0 9.0 多维数组可以每个轴有一个索引。这些索引由一个逗号分割的元组给出。 >>> def f(x,y): ... return 10*x+y ... >>> b = fromfunction(f,(5,4),dtype=int) >>> b array([[ 0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23], [30, 31, 32, 33], [40, 41, 42, 43]]) >>> b[2,3] 23 >>> b[0:5, 1] # each row in the second column of b array([ 1, 11, 21, 31, 41]) >>> b[ : ,1] # equivalent to the previous example array([ 1, 11, 21, 31, 41]) >>> b[1:3, : ] # each column in the second and third row of b array([[10, 11, 12, 13], [20, 21, 22, 23]]) 当少于轴数的索引被提供时,确失的索引被认为是整个切片: >>> b[-1] # the last row. Equivalent to b[-1,:] array([40, 41, 42, 43]) b[i]中括号中的表达式被当作i和一系列:,来代表剩下的轴。NumPy也允许你使用“点”像 b[i,...]。 点(…)代表许多产生一个完整的索引元组必要的分号。如果x是秩为5的数组(即它有5个轴),那么: x[1,2,…] 等同于 x[1,2,:,:,:], x[…,3] 等同于 x[:,:,:,:,3] x[4,…,5,:] 等同 x[4,:,:,5,:]. >>> c = array( [ [[ 0, 1, 2], # a 3D array (two stacked 2D arrays) ... [ 10, 12, 13]], ... ... [[100,101,102], ... [110,112,113]] ] ) >>> c.shape (2, 2, 3) >>> c[1,...] # same as c[1,:,:] or c[1] array([[100, 101, 102], [110, 112, 113]]) >>> c[...,2] # same as c[:,:,2] array([[ 2, 13], [102, 113]]) 迭代多维数组是就第一个轴而言的: >>> for row in b: ... print row ... [0 1 2 3] [10 11 12 13] [20 21 22 23] [30 31 32 33] [40 41 42 43] 然而,如果一个人想对每个数组中元素进行运算,我们可以使用flat属性,该属性是数组元素的一个迭代器: >>> for element in b.flat: ... print element, ... 0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 40 41 42 43 形状操作 更改数组的形状一个数组的形状由它每个轴上的元素个数给出: >>> a = floor(10*random.random((3,4))) >>> a array([[ 7., 5., 9., 3.], [ 7., 2., 7., 8.], [ 6., 8., 3., 2.]]) >>> a.shape (3, 4) 一个数组的形状可以被多种命令修改: >>> a.ravel() # flatten the array array([ 7., 5., 9., 3., 7., 2., 7., 8., 6., 8., 3., 2.]) >>> a.shape = (6, 2) >>> a.transpose() array([[ 7., 9., 7., 7., 6., 3.], [ 5., 3., 2., 8., 8., 2.]]) 由 ravel()展平的数组元素的顺序通常是“C风格”的,就是说,最右边的索引变化得最快,所以元素a[0,0]之后是a[0,1]。如果数组被改变形状(reshape)成其它形状,数组仍然是“C风格”的。NumPy通常创建一个以这个顺序保存数据的数组,所以 ravel()将总是不需要复制它的参数3。但是如果数组是通过切片其它数组或有不同寻常的选项时,它可能需要被复制。函数 reshape()和 ravel()还可以被同过一些可选参数构建成FORTRAN风格的数组,即最左边的索引变化最快。 reshape函数改变参数形状并返回它,而resize函数改变数组自身。 >>> a array([[ 7., 5.], [ 9., 3.], [ 7., 2.], [ 7., 8.], [ 6., 8.], [ 3., 2.]]) >>> a.resize((2,6)) >>> a array([[ 7., 5., 9., 3., 7., 2.], [ 7., 8., 6., 8., 3., 2.]]) 如果在改变形状操作中一个维度被给做-1,其维度将自动被计算 组合(stack)不同的数组 几种方法可以沿不同轴将数组堆叠在一起: >>> a = floor(10*random.random((2,2))) >>> a array([[ 1., 1.], [ 5., 8.]]) >>> b = floor(10*random.random((2,2))) >>> b array([[ 3., 3.], [ 6., 0.]]) >>> vstack((a,b)) array([[ 1., 1.], [ 5., 8.], [ 3., 3.], [ 6., 0.]]) >>> hstack((a,b)) array([[ 1., 1., 3., 3.], [ 5., 8., 6., 0.]]) 函数 column_stack以列将一维数组合成二维数组,它等同与 vstack对一维数组。 >>> column_stack((a,b)) # With 2D arrays array([[ 1., 1., 3., 3.], [ 5., 8., 6., 0.]]) >>> a=array([4.,2.]) >>> b=array([2.,8.]) >>> a[:,newaxis] # This allows to have a 2D columns vector array([[ 4.], [ 2.]]) >>> column_stack((a[:,newaxis],b[:,newaxis])) array([[ 4., 2.], [ 2., 8.]]) >>> vstack((a[:,newaxis],b[:,newaxis])) # The behavior of vstack is different array([[ 4.], [ 2.], [ 2.], [ 8.]]) row_stack函数,另一方面,将一维数组以行组合成二维数组。 对那些维度比二维更高的数组, hstack沿着第二个轴组合, vstack沿着第一个轴组合, concatenate允许可选参数给出组合时沿着的轴。 在复杂情况下, r_[]和 c_[]对创建沿着一个方向组合的数很有用,它们允许范围符号(“:”): >>> r_[1:4,0,4] array([1, 2, 3, 0, 4]) 当使用数组作为参数时,r和c的默认行为和vstack和hstack很像,但是允许可选的参数给出组合所沿着的轴的代号。 将一个数组分割(split)成几个小数组 使用 hsplit你能将数组沿着它的水平轴分割,或者指定返回相同形状数组的个数,或者指定在哪些列后发生分割: >>> a = floor(10*random.random((2,12))) >>> a array([[ 8., 8., 3., 9., 0., 4., 3., 0., 0., 6., 4., 4.], [ 0., 3., 2., 9., 6., 0., 4., 5., 7., 5., 1., 4.]]) >>> hsplit(a,3) # Split a into 3 [array([[ 8., 8., 3., 9.], [ 0., 3., 2., 9.]]), array([[ 0., 4., 3., 0.], [ 6., 0., 4., 5.]]), array([[ 0., 6., 4., 4.], [ 7., 5., 1., 4.]])] >>> hsplit(a,(3,4)) # Split a after the third and the fourth column [array([[ 8., 8., 3.], [ 0., 3., 2.]]), array([[ 9.], [ 9.]]), array([[ 0., 4., 3., 0., 0., 6., 4., 4.], [ 6., 0., 4., 5., 7., 5., 1., 4.]])] vsplit沿着纵向的轴分割, array split允许指定沿哪个轴分割。 复制和视图当运算和处理数组时,它们的数据有时被拷贝到新的数组有时不是。这通常是新手的困惑之源。这有三种情况:完全不拷贝简单的赋值不拷贝数组对象或它们的数据。 >>> a = arange(12) >>> b = a # no new object is created >>> b is a # a and b are two names for the same ndarray object True >>> b.shape = 3,4 # changes the shape of a >>> a.shape (3, 4) Python 传递不定对象作为参考,所以函数调用不拷贝数组。 >>> def f(x): ... print id(x) ... >>> id(a) # id is a unique identifier of an object 148293216 >>> f(a) 148293216 视图(view)和浅复制 不同的数组对象分享同一个数据。视图方法创造一个新的数组对象指向同一数据。 >>> c = a.view() >>> c is a False >>> c.base is a # c is a view of the data owned by a True >>> c.flags.owndata False >>> >>> c.shape = 2,6 # a's shape doesn't change >>> a.shape (3, 4) >>> c[0,4] = 1234 # a's data changes >>> a array([[ 0, 1, 2, 3], [1234, 5, 6, 7], [ 8, 9, 10, 11]]) 切片数组返回它的一个视图: >>> s = a[ : , 1:3] # spaces added for clarity; could also be written "s = a[:,1:3]" >>> s[:] = 10 # s[:] is a view of s. Note the difference between s=10 and s[:]=10 >>> a array([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]]) 深复制 这个复制方法完全复制数组和它的数据。 >>> d = a.copy() # a new array object with new data is created >>> d is a False >>> d.base is a # d doesn't share anything with a False >>> d[0,0] = 9999 >>> a array([[ 0, 10, 10, 3], [1234, 10, 10, 7], [ 8, 10, 10, 11]]) 函数和方法(method)总览 创建数组 arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r , zeros, zeros_like 转化 astype, atleast 1d, atleast 2d, atleast 3d, mat 操作 array split, column stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack 询问 all, any, nonzero, where 排序 argmax, argmin, argsort, max, min, ptp, searchsorted, sort 运算 choose, compress, cumprod, cumsum, inner, fill, imag, prod, put, putmask, real, sum 基本统计 cov, mean, std, var 基本线性代数 cross, dot, outer, svd, vdot 进阶 广播法则(rule) 广播法则能使通用函数有意义地处理不具有相同形状的输入。 广播第一法则是,如果所有的输入数组维度不都相同,一个“1”将被重复地添加在维度较小的数组上直至所有的数组拥有一样的维度。 广播第二法则确定长度为1的数组沿着特殊的方向表现地好像它有沿着那个方向最大形状的大小。对数组来说,沿着那个维度的数组元素的值理应相同。 应用广播法则之后,所有数组的大小必须匹配。更多细节可以从这个文档找到。 花哨的索引和索引技巧 NumPy比普通Python序列提供更多的索引功能。除了索引整数和切片,正如我们之前看到的,数组可以被整数数组和布尔数组索引。 通过数组索引 >>> a = arange(12)**2 # the first 12 square numbers >>> i = array( [ 1,1,3,8,5 ] ) # an array of indices >>> a[i] # the elements of a at the positions i array([ 1, 1, 9, 64, 25]) >>> >>> j = array( [ [ 3, 4], [ 9, 7 ] ] ) # a bidimensional array of indices >>> a[j] # the same shape as j array([[ 9, 16], [81, 49]]) 当被索引数组a是多维的时,每一个唯一的索引数列指向a的第一维。以下示例通过将图片标签用调色版转换成色彩图像展示了这种行为。 >>> palette = array( [ [0,0,0], # black ... [255,0,0], # red ... [0,255,0], # green ... [0,0,255], # blue ... [255,255,255] ] ) # white >>> image = array( [ [ 0, 1, 2, 0 ], # each value corresponds to a color in the palette ... [ 0, 3, 4, 0 ] ] ) >>> palette[image] # the (2,4,3) color image array([[[ 0, 0, 0], [255, 0, 0], [ 0, 255, 0], [ 0, 0, 0]], [[ 0, 0, 0], [ 0, 0, 255], [255, 255, 255], [ 0, 0, 0]]]) 我们也可以给出不不止一维的索引,每一维的索引数组必须有相同的形状。 >>> a = arange(12).reshape(3,4) >>> a array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> i = array( [ [0,1], # indices for the first dim of a ... [1,2] ] ) >>> j = array( [ [2,1], # indices for the second dim ... [3,3] ] ) >>> >>> a[i,j] # i and j must have equal shape array([[ 2, 5], [ 7, 11]]) >>> >>> a[i,2] array([[ 2, 6], [ 6, 10]]) >>> >>> a[:,j] # i.e., a[ : , j] array([[[ 2, 1], [ 3, 3]], [[ 6, 5], [ 7, 7]], [[10, 9], [11, 11]]]) 自然,我们可以把i和j放到序列中(比如说列表)然后通过list索引。 >>> l = [i,j] >>> a[l] # equivalent to a[i,j] array([[ 2, 5], [ 7, 11]]) 然而,我们不能把i和j放在一个数组中,因为这个数组将被解释成索引a的第一维。 >>> s = array( [i,j] ) >>> a[s] # not what we want --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-100-b912f631cc75> in <module>() ----> 1 a[s] IndexError: index (3) out of range (0<=index<2) in dimension 0 >>> >>> a[tuple(s)] # same as a[i,j] array([[ 2, 5], [ 7, 11]]) 另一个常用的数组索引用法是搜索时间序列最大值。 >>> time = linspace(20, 145, 5) # time scale >>> data = sin(arange(20)).reshape(5,4) # 4 time-dependent series >>> time array([ 20. , 51.25, 82.5 , 113.75, 145. ]) >>> data array([[ 0. , 0.84147098, 0.90929743, 0.14112001], [-0.7568025 , -0.95892427, -0.2794155 , 0.6569866 ], [ 0.98935825, 0.41211849, -0.54402111, -0.99999021], [-0.53657292, 0.42016704, 0.99060736, 0.65028784], [-0.28790332, -0.96139749, -0.75098725, 0.14987721]]) >>> >>> ind = data.argmax(axis=0) # index of the maxima for each series >>> ind array([2, 0, 3, 1]) >>> >>> time_max = time[ ind] # times corresponding to the maxima >>> >>> data_max = data[ind, xrange(data.shape[1])] # => data[ind[0],0], data[ind[1],1]... >>> >>> time_max array([ 82.5 , 20. , 113.75, 51.25]) >>> data_max array([ 0.98935825, 0.84147098, 0.99060736, 0.6569866 ]) >>> >>> all(data_max == data.max(axis=0)) True 你也可以使用数组索引作为目标来赋值: >>> a = arange(5) >>> a array([0, 1, 2, 3, 4]) >>> a[[1,3,4]] = 0 >>> a array([0, 0, 2, 0, 0]) 然而,当一个索引列表包含重复时,赋值被多次完成,保留最后的值: >>> a = arange(5) >>> a[[0,0,2]]=[1,2,3] >>> a array([2, 1, 3, 3, 4]) 这足够合理,但是小心如果你想用Python的+=结构,可能结果并非你所期望: >>> a = arange(5) >>> a[[0,0,2]]+=1 >>> a array([1, 1, 3, 3, 4]) 即使0在索引列表中出现两次,索引为0的元素仅仅增加一次。这是因为Python要求a+=1和a=a+1等同。 通过布尔数组索引 当我们使用整数数组索引数组时,我们提供一个索引列表去选择。通过布尔数组索引的方法是不同的我们显式地选择数组中我们想要和不想要的元素。 我们能想到的使用布尔数组的索引最自然方式就是使用和原数组一样形状的布尔数组。 >>> a = arange(12).reshape(3,4) >>> b = a > 4 >>> b # b is a boolean with a's shape array([[False, False, False, False], [False, True, True, True], [True, True, True, True]], dtype=bool) >>> a[b] # 1d array with the selected elements array([ 5, 6, 7, 8, 9, 10, 11]) 这个属性在赋值时非常有用: >>> a[b] = 0 # All elements of 'a' higher than 4 become 0 >>> a array([[0, 1, 2, 3], [4, 0, 0, 0], [0, 0, 0, 0]]) 第二种通过布尔来索引的方法更近似于整数索引;对数组的每个维度我们给一个一维布尔数组来选择我们想要的切片。 >>> a = arange(12).reshape(3,4) >>> b1 = array([False,True,True]) # first dim selection >>> b2 = array([True,False,True,False]) # second dim selection >>> >>> a[b1,:] # selecting rows array([[ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> a[b1] # same thing array([[ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> >>> a[:,b2] # selecting columns array([[ 0, 2], [ 4, 6], [ 8, 10]]) >>> >>> a[b1,b2] # a weird thing to do array([ 4, 10]) 注意一维数组的长度必须和你想要切片的维度或轴的长度一致,在之前的例子中,b1是一个秩为1长度为三的数组(a的行数),b2(长度为4)与a的第二秩(列)相一致. ix_()函数 ix_函数可以为了获得多元组的结果而用来结合不同向量。例如,如果你想要用所有向量a、b和c元素组成的三元组来计算 a+b*c: >>> a = array([2,3,4,5]) >>> b = array([8,5,4]) >>> c = array([5,4,6,8,3]) >>> ax,bx,cx = ix_(a,b,c) >>> ax array([[[2]], [[3]], [[4]], [[5]]]) >>> bx array([[[8], [5], [4]]]) >>> cx array([[[5, 4, 6, 8, 3]]]) >>> ax.shape, bx.shape, cx.shape ((4, 1, 1), (1, 3, 1), (1, 1, 5)) >>> result = ax+bx*cx >>> result array([[[42, 34, 50, 66, 26], [27, 22, 32, 42, 17], [22, 18, 26, 34, 14]], [[43, 35, 51, 67, 27], [28, 23, 33, 43, 18], [23, 19, 27, 35, 15]], [[44, 36, 52, 68, 28], [29, 24, 34, 44, 19], [24, 20, 28, 36, 16]], [[45, 37, 53, 69, 29], [30, 25, 35, 45, 20], [25, 21, 29, 37, 17]]]) >>> result[3,2,4] 17 >>> a[3]+b[2]*c[4] 17 你也可以实行如下简化: def ufunc_reduce(ufct, *vectors): vs = ix_(*vectors) r = ufct.identity for v in vs: r = ufct(r,v) return r 然后这样使用它: >>> ufunc_reduce(add,a,b,c) array([[[15, 14, 16, 18, 13], [12, 11, 13, 15, 10], [11, 10, 12, 14, 9]], [[16, 15, 17, 19, 14], [13, 12, 14, 16, 11], [12, 11, 13, 15, 10]], [[17, 16, 18, 20, 15], [14, 13, 15, 17, 12], [13, 12, 14, 16, 11]], [[18, 17, 19, 21, 16], [15, 14, 16, 18, 13], [14, 13, 15, 17, 12]]]) 这个reduce与ufunc.reduce(比如说add.reduce)相比的优势在于它利用了广播法则,避免了创建一个输出大小乘以向量个数的参数数组。 线性代数 简单数组运算 >>> from numpy import * >>> from numpy.linalg import * >>> a = array([[1.0, 2.0], [3.0, 4.0]]) >>> print a [[ 1. 2.] [ 3. 4.]] >>> a.transpose() array([[ 1., 3.], [ 2., 4.]]) >>> inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> u = eye(2) # unit 2x2 matrix; "eye" represents "I" >>> u array([[ 1., 0.], [ 0., 1.]]) >>> j = array([[0.0, -1.0], [1.0, 0.0]]) >>> dot (j, j) # matrix product array([[-1., 0.], [ 0., -1.]]) >>> trace(u) # trace 2.0 >>> y = array([[5.], [7.]]) >>> solve(a, y) array([[-3.], [ 4.]]) >>> eig(j) (array([ 0.+1.j, 0.-1.j]), array([[ 0.70710678+0.j, 0.70710678+0.j], [ 0.00000000-0.70710678j, 0.00000000+0.70710678j]])) Parameters: square matrix Returns The eigenvalues, each repeated according to its multiplicity. The normalized (unit "length") eigenvectors, such that the column ``v[:,i]`` is the eigenvector corresponding to the eigenvalue ``w[i]`` . 矩阵类 这是一个关于矩阵类的简短介绍。 >>> A = matrix('1.0 2.0; 3.0 4.0') >>> A [[ 1. 2.] [ 3. 4.]] >>> type(A) # file where class is defined <class 'numpy.matrixlib.defmatrix.matrix'> >>> A.T # transpose [[ 1. 3.] [ 2. 4.]] >>> X = matrix('5.0 7.0') >>> Y = X.T >>> Y [[5.] [7.]] >>> print A*Y # matrix multiplication [[19.] [43.]] >>> print A.I # inverse [[-2. 1. ] [ 1.5 -0.5]] >>> solve(A, Y) # solving linear equation matrix([[-3.], [ 4.]]) 索引:比较矩阵和二维数组 注意NumPy中数组和矩阵有些重要的区别。NumPy提供了两个基本的对象:一个N维数组对象和一个通用函数对象。其它对象都是建构在它们之上 的。特别的,矩阵是继承自NumPy数组对象的二维数组对象。对数组和矩阵,索引都必须包含合适的一个或多个这些组合:整数标量、省略号 (ellipses)、整数列表;布尔值,整数或布尔值构成的元组,和一个一维整数或布尔值数组。矩阵可以被用作矩阵的索引,但是通常需要数组、列表或者 其它形式来完成这个任务。 像平常在Python中一样,索引是从0开始的。传统上我们用矩形的行和列表示一个二维数组或矩阵,其中沿着0轴的方向被穿过的称作行,沿着1轴的方向被穿过的是列。 让我们创建数组和矩阵用来切片 >>> A = arange(12) >>> A array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) >>> A.shape = (3,4) >>> M = mat(A.copy()) >>> print type(A)," ",type(M) <type 'numpy.ndarray'> <class 'numpy.core.defmatrix.matrix'> >>> print A [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] >>> print M [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]]现在,让我们简单的切几片。基本的切片使用切片对象或整数。例如, A[:]和 M[:]的求值将表现得和Python索引很相似。然而要注意很重要的一点就是NumPy切片数组不创建数据的副本;切片提供统一数据的视图。 >>> print A[:]; print A[:].shape [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] (3, 4) >>> print M[:]; print M[:].shape [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] (3, 4)现在有些和Python索引不同的了:你可以同时使用逗号分割索引来沿着多个轴索引。 >>> print A[:,1]; print A[:,1].shape [1 5 9] (3,) >>> print M[:,1]; print M[:,1].shape [[1] [5] [9]] (3, 1) 注意最后两个结果的不同。对二维数组使用一个冒号产生一个一维数组,然而矩阵产生了一个二维矩阵。10例如,一个M[2,:]切片产生了一个形状为(1,4)的矩阵,相比之下,一个数组的切片总是产生一个最低可能维度11的数组。例如,如果C是一个三维数组,C[...,1]产生一个二维的数组而C[1,:,1]产生一个一维数组。从这时开始,如果相应的矩阵切片结果是相同的话,我们将只展示数组切片的结果。 假如我们想要一个数组的第一列和第三列,一种方法是使用列表切片 >>> A[:,[1,3]] array([[ 1, 3], [ 5, 7], [ 9, 11]])稍微复杂点的方法是使用 take()方法(method): >>> A[:,].take([1,3],axis=1) array([[ 1, 3], [ 5, 7], [ 9, 11]]) 如果我们想跳过第一行,我们可以这样: >>> A[1:,].take([1,3],axis=1) array([[ 5, 7], [ 9, 11]]) 或者我们仅仅使用 A[1:,[1,3]]。还有一种方法是通过矩阵向量积(叉积)。 >>> A[ix_((1,2),(1,3))] array([[ 5, 7], [ 9, 11]]) 为了读者的方便,在次写下之前的矩阵: >>> A[ix_((1,2),(1,3))] array([[ 5, 7], [ 9, 11]]) 现在让我们做些更复杂的。比如说我们想要保留第一行大于1的列。一种方法是创建布尔索引: >>> A[0,:]>1 array([False, False, True, True], dtype=bool) >>> A[:,A[0,:]>1] array([[ 2, 3], [ 6, 7], [10, 11]])就是我们想要的!但是索引矩阵没这么方便。 >>> M[0,:]>1 matrix([[False, False, True, True]], dtype=bool) >>> M[:,M[0,:]>1] matrix([[2, 3]]) 这个过程的问题是用“矩阵切片”来切片产生一个矩阵,但是矩阵有个方便的A属性,它的值是数组呈现的。所以我们仅仅做以下替代: >>> M[:,M.A[0,:]>1] matrix([[ 2, 3], [ 6, 7], [10, 11]]) 如果我们想要在矩阵两个方向有条件地切片,我们必须稍微调整策略,代之以: >>> A[A[:,0]>2,A[0,:]>1] array([ 6, 11]) >>> M[M.A[:,0]>2,M.A[0,:]>1] matrix([[ 6, 11]]) 我们需要使用向量积 ix_: >>> A[ix_(A[:,0]>2,A[0,:]>1)] array([[ 6, 7], [10, 11]]) >>> M[ix_(M.A[:,0]>2,M.A[0,:]>1)] matrix([[ 6, 7], [10, 11]]) 技巧和提示 下面我们给出简短和有用的提示。 “自动”改变形状 更改数组的维度,你可以省略一个尺寸,它将被自动推导出来。 >>> a = arange(30) >>> a.shape = 2,-1,3 # -1 means "whatever is needed" >>> a.shape (2, 5, 3) >>> a array([[[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14]], [[15, 16, 17], [18, 19, 20], [21, 22, 23], [24, 25, 26], [27, 28, 29]]]) 向量组合(stacking) 我们如何用两个相同尺寸的行向量列表构建一个二维数组?在MATLAB中这非常简单:如果x和y是两个相同长度的向量,你仅仅需要做 m=[x;y]。在NumPy中这个过程通过函数 column_stack、 dstack、 hstack和 vstack来完成,取决于你想要在那个维度上组合。例如: x = arange(0,10,2) # x=([0,2,4,6,8]) y = arange(5) # y=([0,1,2,3,4]) m = vstack([x,y]) # m=([[0,2,4,6,8], # [0,1,2,3,4]]) xy = hstack([x,y]) # xy =([0,2,4,6,8,0,1,2,3,4]) 直方图(histogram) NumPy中histogram函数应用到一个数组返回一对变量:直方图数组和箱式向量。注意:matplotlib也有一个用来建立直方图的函数(叫作hist,正如matlab中一样)与NumPy中的不同。主要的差别是pylab.hist自动绘制直方图,而numpy.histogram仅仅产生数据。 import numpy import pylab # Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2 mu, sigma = 2, 0.5 v = numpy.random.normal(mu,sigma,10000) # Plot a normalized histogram with 50 bins pylab.hist(v, bins=50, normed=1) # matplotlib version (plot) pylab.show() # Compute the histogram with numpy and then plot it (n, bins) = numpy.histogram(v, bins=50, normed=True) # NumPy version (no plot) pylab.plot(.5*(bins[1:]+bins[:-1]), n) pylab.show() 原文发布时间为:2018-12-5 本文作者:机器学习算法与Python学习 本文来自云栖社区合作伙伴“ 机器学习算法与Python学习”,了解相关信息可以关注“guodongwei1991”微信公众号

优秀的个人博客,低调大师

ubuntu 安装Docker教程

Linux环境 Ubuntu 16.04(LTS) 简单方法 $ sudo apt-get update $ sudo apt-get install docker 搞定!但是这种方法有一个缺点:安装的不一定是最新的docker,安装版本是1.10.2,不过,对于docker使用没任何什么问题,如果要后续升级方便,可以使用下面的方法。 另一种方法 1.切换到root权限或者用sudo 2.升级source列表并保证https和ca证书成功安装 apt-get update apt-get install apt-transport-https ca-certificates 3.增加新的GPG 密钥 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9 4.新增或编辑source列表里的docker.list文件 sudo sh -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list" 5.删除已有的entries 6.按照系统版本增加entry(Ubuntu Xenial 16.04 (LTS)) sudo sh -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list" 7.重新执行更新操作,并删除老的repo apt-get purge lxc-docker //没有安装的话,跳过 8.查看是否有正确的可用版本 apt-cache policy docker-engine docker-engine: 已安装:(无) 候选: 1.12.4-0~ubuntu-xenial 版本列表: 1.12.4-0~ubuntu-xenial 500 500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages 1.12.3-0~xenial 500 500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages 1.12.2-0~xenial 500 500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages 1.12.1-0~xenial 500 500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages 1.12.0-0~xenial 500 500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages 1.11.2-0~xenial 500 500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages 1.11.1-0~xenial 500 500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages 1.11.0-0~xenial 500 500 https://apt.dockerproject.org/repo ubuntu-xenial/main amd64 Packages 9.从14.04版本以上开始docker推荐安装linux-image-extra apt-get install linux-image-extra-$(uname -r) 10.安装docker apt-get update apt-get install docker-engine service docker start docker run hello-world 到此结束,the end! docker --version Docker version 1.12.4, build 1564f02

优秀的个人博客,低调大师

Spring框架教程集合

Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。 ● Spring框架是什么? ● Spring框架的体系结构 ● Spring 环境安装配置 ● Spring Hello World 实例 ● Spring IoC容器 ● Spring BeanFactory容器 ● Spring bean定义 ● Spring Bean Scopes作用域 ● Spring bean 生命周期 ● Spring发布处理器 ● Spring bean定义继承 ● Spring 依赖注入 ● Spring注入内部bean ● Spring注入集合 ● Spring自动装配和注解配置 ● Spring 基于Java配置 ● Spring事件处理 ● Spring框架的AOP ● Spring JDBC框架 ● Spring中的事务管理详解 ● SpringMVC工作原理 ●Spring整合log4j日志组件 原文发布时间为:2018-11-2 本文作者:HARRIES 本文来自云栖社区合作伙伴“Java杂记”,了解相关信息可以关注“Java杂记”。

优秀的个人博客,低调大师

Django入门教程

Django之与Python,就好比Laravel之与PHP,Java的Spring Boot,都提供了很多开箱即用的东西,刚入门Python的人因为Python生态体系不是很熟,使用Django做Web开发因为其提供了开发的很多工具,可以大大开发我们的效率。 在Python熟悉之后,Django用熟练了,可以切换到一些更灵活的轻量级的框架上,如Flask。虽然Django相对重量级一些,但是使用起来还是很方便的,一块看看其怎么使用吧。 环境准备 Python3.6 Django2.0 过程 如果使用的是Mac系统,或者*nix系统,系统默认的Python版本可能是2.x的,这时需要装一些额外的工具来使用Python3.x的版本。 Pyenv 简单的Python版本管理工具 安装好Pyenv之后,你的系统就可以任意切换Python的版本了。 确保当前使用的是Python3.6版本的情况下,安装Django .python-version文件是pyenv控制当前目录下python版本的文件,其只影响当前目录的pythhon版本 pip安装的时候指定的django的版本号 image.png 创建Django的项目,Django给我们提供了一些命令可以直接新建一个项目。 django-admin startproject demo 这条命令会在当前目录下创建demo目录,另外看下django-admin支持的命令 image.png Django项目的目录解释 image.png demo 我们创建的是demo项目,总目录名称就是demo demo/demo ,是Python的包名,这个目录下的东西一般是用于其他项目导入的。个人理解为,demo项目下的东西不可能所有的都暴露出来,与项目名同名的目录才暴露出来 manage.py django的命令行工具 其余几个文件,如其名,setting.py配置django项目的,urls.py声明式的URL。wsgi.py配置webserver的。 Django项目内管理工具, 项目内的manage.py也给我们提供了很多命令行工具,预览一下。 image.png 启动项目,到这里我们的项目基本上是可以运行起来了,是不是很简单。 python manage.py runserver // 运行时指定端口 // python manage.py runserver ipaddr:port image.png 红色的错误先不用担心,它提示我们要先运行python manage.py migrate命令 image.png 额外 django工具命令参考 最后 这次我们以能正常的启动项目结束,接下来的文章写django的用法

优秀的个人博客,低调大师

python 基础教程

运算 !/usr/bin/python -- coding: UTF-8 -- a = 21 b = 10 c = 0 c = a + b print "1 - c 的值为:", c c = a - b print "2 - c 的值为:", c c = a * b print "3 - c 的值为:", c c = a / b print "4 - c 的值为:", c c = a % b print "5 - c 的值为:", c 修改变量 a 、b 、c a = 2 b = 3 c = a**b print "6 - c 的值为:", c a = 10 b = 5 c = a//b print "7 - c 的值为:", c python比较 !/usr/bin/python -- coding: UTF-8 -- a = 21 b = 10 c = 0 if ( a == b ): print "1 - a 等于 b" else: print "1 - a 不等于 b" if ( a != b ): print "2 - a 不等于 b" else: print "2 - a 等于 b" if ( a <> b ): print "3 - a 不等于 b" else: print "3 - a 等于 b" if ( a < b ): print "4 - a 小于 b" else: print "4 - a 大于等于 b" if ( a > b ): print "5 - a 大于 b" else: print "5 - a 小于等于 b" 修改变量 a 和 b 的值 a = 5 b = 20 if ( a <= b ): print "6 - a 小于等于 b" else: print "6 - a 大于 b" if ( b >= a ): print "7 - b 大于等于 a" else: print "7 - b 小于 a" 赋值 !/usr/bin/python -- coding: UTF-8 -- a = 21 b = 10 c = 0 c = a + b print "1 - c 的值为:", c c += a print "2 - c 的值为:", c c *= a print "3 - c 的值为:", c c /= a print "4 - c 的值为:", c c = 2 c %= a print "5 - c 的值为:", c c **= a print "6 - c 的值为:", c c //= a print "7 - c 的值为:", c 逻辑运算符: !/usr/bin/python -- coding: UTF-8 -- a = 10 b = 20 if ( a and b ): print "1 - 变量 a 和 b 都为 true" else: print "1 - 变量 a 和 b 有一个不为 true" if ( a or b ): print "2 - 变量 a 和 b 都为 true,或其中一个变量为 true" else: print "2 - 变量 a 和 b 都不为 true" 修改变量 a 的值 a = 0 if ( a and b ): print "3 - 变量 a 和 b 都为 true" else: print "3 - 变量 a 和 b 有一个不为 true" if ( a or b ): print "4 - 变量 a 和 b 都为 true,或其中一个变量为 true" else: print "4 - 变量 a 和 b 都不为 true" if not( a and b ): print "5 - 变量 a 和 b 都为 false,或其中一个变量为 false" else: print "5 - 变量 a 和 b 都为 true" in,not in !/usr/bin/python -- coding: UTF-8 -- a = 10 b = 20 list = [1, 2, 3, 4, 5 ]; if ( a in list ): print "1 - 变量 a 在给定的列表中 list 中" else: print "1 - 变量 a 不在给定的列表中 list 中" if ( b not in list ): print "2 - 变量 b 不在给定的列表中 list 中" else: print "2 - 变量 b 在给定的列表中 list 中" 修改变量 a 的值 a = 2 if ( a in list ): print "3 - 变量 a 在给定的列表中 list 中" else: print "3 - 变量 a 不在给定的列表中 list 中" 条件 !/usr/bin/python -- coding: UTF-8 -- 例1:if 基本用法 flag = False name = 'luren' if name == 'python': # 判断变量否为'python' flag = True # 条件成立时设置标志为真 print 'welcome boss' # 并输出欢迎信息 else: print name !/usr/bin/python -- coding: UTF-8 -- 例2:elif用法 num = 5 if num == 3: # 判断num的值 print 'boss' elif num == 2: print 'user' elif num == 1: print 'worker' elif num < 0: # 值小于零时输出 print 'error' else: print 'roadman' # 条件均不成立时输出 循环语句: !/usr/bin/python count = 0 while (count < 9): print 'The count is:', count count = count + 1 print "Good bye!" i = 1 while i < 10: i += 1 if i%2 > 0: # 非双数时跳过输出 continue print i # 输出双数2、4、6、8、10 i = 1 while 1: # 循环条件为1必定成立 print i # 输出1~10 i += 1 if i > 10: # 当i大于10时跳出循环 break !/usr/bin/python -- coding: UTF-8 -- for letter in 'Python': # 第一个实例 print '当前字母 :', letter fruits = ['banana', 'apple', 'mango'] for fruit in fruits: # 第二个实例 print '当前水果 :', fruit print "Good bye!" 获取用户输入:raw_input !/usr/bin/python -- coding: UTF-8 -- var = 1 while var == 1 : # 该条件永远为true,循环将无限执行下去 num = raw_input("Enter a number :") print "You entered: ", num print "Good bye!" range,len !/usr/bin/python -- coding: UTF-8 -- fruits = ['banana', 'apple', 'mango'] for index in range(len(fruits)): print '当前水果 :', fruits[index] print "Good bye!" import cmath cmath.sqrt(-1) 1j cmath.sqrt(9) (3+0j) cmath.sin(1) (0.8414709848078965+0j) cmath.log10(100) (2+0j) python数学函数: abs,cell,cmp,exp,fabs,floor,log,log10,max,min,mod,pow,round,sqrt randrange image.png image.png 访问字符串的值 !/usr/bin/python var1 = 'Hello World!' var2 = "Python Runoob" print "var1[0]: ", var1[0] print "var2[1:5]: ", var2[1:5] 转义字符 image.png 格式化输出 print "My name is %s and weight is %d kg!" % ('Zara', 21) image.png 字符串函数: image.png image.png image.png image.png 添加元素 !/usr/bin/python -- coding: UTF-8 -- list = [] ## 空列表 list.append('Google') ## 使用 append() 添加元素 list.append('Runoob') print list 删除元素 !/usr/bin/python list1 = ['physics', 'chemistry', 1997, 2000] print list1 del list1[2] print "After deleting value at index 2 : " print list1 列表操作 image.png 列表方法 image.png 删除字典 !/usr/bin/python -- coding: UTF-8 -- dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}; del dict['Name']; # 删除键是'Name'的条目 dict.clear(); # 清空词典所有条目 del dict ; # 删除词典 print "dict['Age']: ", dict['Age']; print "dict['School']: ", dict['School']; 字典的函数: image.png image.png 当前时间戳: import time time.time() 格式化日期输出 !/usr/bin/python -- coding: UTF-8 -- import time 格式化成2016-03-20 11:45:39形式 print time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 格式化成Sat Mar 28 22:24:24 2016形式 print time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()) 将格式字符串转换为时间戳 a = "Sat Mar 28 22:24:24 2016" print time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y")) 获取某个月日历:calendar !/usr/bin/python -- coding: UTF-8 -- import calendar cal = calendar.month(2016, 1) print "以下输出2016年1月份的日历:" print cal 当前日期和时间 !/usr/bin/python -- coding: UTF-8 -- import datetime i = datetime.datetime.now() print ("当前的日期和时间是 %s" % i) print ("ISO格式的日期和时间是 %s" % i.isoformat() ) print ("当前的年份是 %s" %i.year) print ("当前的月份是 %s" %i.month) print ("当前的日期是 %s" %i.day) print ("dd/mm/yyyy 格式是 %s/%s/%s" % (i.day, i.month, i.year) ) print ("当前小时是 %s" %i.hour) print ("当前分钟是 %s" %i.minute) print ("当前秒是 %s" %i.second) 不定长参数:* image.png lambda:匿名函数 image.png def.... python模块搜索路径 image.png 获取用户输入 !/usr/bin/python -- coding: UTF-8 -- str = raw_input("请输入:") print "你输入的内容是: ", str input可以接收表达式 image.png open参数 image.png image.png image.png write要自己添加换行符 读取10个字符 image.png 重命名:os.rename os.remove os.mkdir os.chdir os.getcwd os.rmdir open参数 image.png file的方法 image.png image.png 异常: !/usr/bin/python -- coding: UTF-8 -- try: fh = open("testfile", "w") fh.write("这是一个测试文件,用于测试异常!!") except IOError: print "Error: 没有找到文件或读取文件失败" else: print "内容写入文件成功" fh.close() !/usr/bin/python -- coding: UTF-8 -- try: fh = open("testfile", "w") fh.write("这是一个测试文件,用于测试异常!!") finally: print "Error: 没有找到文件或读取文件失败" 用户自定义异常: image.png Python OS 文件/目录方法 os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示: | 序号 | 方法及描述 | | 1 | os.access(path, mode) 检验权限模式 | | 2 | os.chdir(path) 改变当前工作目录 | | 3 | os.chflags(path, flags) 设置路径的标记为数字标记。 | | 4 | os.chmod(path, mode) 更改权限 | | 5 | os.chown(path, uid, gid) 更改文件所有者 | | 6 | os.chroot(path) 改变当前进程的根目录 | | 7 | os.close(fd) 关闭文件描述符 fd | | 8 | os.closerange(fd_low, fd_high) 关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略 | | 9 | os.dup(fd) 复制文件描述符 fd | | 10 | os.dup2(fd, fd2) 将一个文件描述符 fd 复制到另一个 fd2 | | 11 | os.fchdir(fd) 通过文件描述符改变当前工作目录 | | 12 | os.fchmod(fd, mode) 改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。 | | 13 | os.fchown(fd, uid, gid) 修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。 | | 14 | os.fdatasync(fd) 强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。 | | 15 | os.fdopen(fd[, mode[, bufsize]]) 通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 | | 16 | os.fpathconf(fd, name) 返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。 | | 17 | os.fstat(fd) 返回文件描述符fd的状态,像stat()。 | | 18 | os.fstatvfs(fd) 返回包含文件描述符fd的文件的文件系统的信息,像 statvfs() | | 19 | os.fsync(fd) 强制将文件描述符为fd的文件写入硬盘。 | | 20 | os.ftruncate(fd, length) 裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。 | | 21 | os.getcwd() 返回当前工作目录 | | 22 | os.getcwdu() 返回一个当前工作目录的Unicode对象 | | 23 | os.isatty(fd) 如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。 | | 24 | os.lchflags(path, flags) 设置路径的标记为数字标记,类似 chflags(),但是没有软链接 | | 25 | os.lchmod(path, mode) 修改连接文件权限 | | 26 | os.lchown(path, uid, gid) 更改文件所有者,类似 chown,但是不追踪链接。 | | 27 | os.link(src, dst) 创建硬链接,名为参数 dst,指向参数 src | | 28 | os.listdir(path) 返回path指定的文件夹包含的文件或文件夹的名字的列表。 | | 29 | os.lseek(fd, pos, how) 设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效 | | 30 | os.lstat(path) 像stat(),但是没有软链接 | | 31 | os.major(device) 从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。 | | 32 | os.makedev(major, minor) 以major和minor设备号组成一个原始设备号 | | 33 | os.makedirs(path[, mode]) 递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。 | | 34 | os.minor(device) 从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。 | | 35 | os.mkdir(path[, mode]) 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 | | 36 | os.mkfifo(path[, mode]) 创建命名管道,mode 为数字,默认为 0666 (八进制) | | 37 | os.mknod(filename[, mode=0600, device]) 创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。 | | 38 | os.open(file, flags[, mode]) 打开一个文件,并且设置需要的打开选项,mode参数是可选的 | | 39 | os.openpty() 打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 | | 40 | os.pathconf(path, name) 返回相关文件的系统配置信息。 | | 41 | os.pipe() 创建一个管道. 返回一对文件描述符(r, w) 分别为读和写 | | 42 | os.popen(command[, mode[, bufsize]]) 从一个 command 打开一个管道 | | 43 | os.read(fd, n) 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。 | | 44 | os.readlink(path) 返回软链接所指向的文件 | | 45 | os.remove(path) 删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。 | | 46 | os.removedirs(path) 递归删除目录。 | | 47 | os.rename(src, dst) 重命名文件或目录,从 src 到 dst | | 48 | os.renames(old, new) 递归地对目录进行更名,也可以对文件进行更名。 | | 49 | os.rmdir(path) 删除path指定的空目录,如果目录非空,则抛出一个OSError异常。 | | 50 | os.stat(path) 获取path指定的路径的信息,功能等同于C API中的stat()系统调用。 | | 51 | os.stat_float_times([newvalue]) 决定stat_result是否以float对象显示时间戳 | | 52 | os.statvfs(path) 获取指定路径的文件系统统计信息 | | 53 | os.symlink(src, dst) 创建一个软链接 | | 54 | os.tcgetpgrp(fd) 返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组 | | 55 | os.tcsetpgrp(fd, pg) 设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。 | | 56 | os.tempnam([dir[, prefix]]) 返回唯一的路径名用于创建临时文件。 | | 57 | os.tmpfile() 返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。 | | 58 | os.tmpnam() 为创建一个临时文件返回一个唯一的路径 | | 59 | os.ttyname(fd) 返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 | | 60 | os.unlink(path) 删除文件路径 | | 61 | os.utime(path, times) 返回指定的path文件的访问和修改的时间。 | | 62 | os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]]) 输出在文件夹中的文件名通过在树中游走,向上或者向下。 | | 63 | os.write(fd, str) 写入字符串到文件描述符 fd中. 返回实际写入的字符串长度 |

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册