numpy下载太慢(为啥我的Python这么慢)

:暂无数据 2026-08-19 12:20:04 :0

numpy下载太慢(为啥我的Python这么慢)

大家好,关于numpy下载太慢很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于为啥我的Python这么慢的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!

本文目录

为啥我的Python这么慢

Pythn是动态类型而不是静态类型的,这意味着,在程序执行时,解释器并不知道变量的类型。对C语言来说,编译器在声明变量的时候就知道其类型了;对Python来说,程序执行时只知道一个变量是某种Python对象。
对于下面的C代码
int a = 1;
int b = 2;
int c = a + b;
编译器始终知道a和b是整型,在执行相加运算时,流程如下:
把《int》 1赋值给a
把《int》 2赋值给b
调用binary_add《int, int》(a, b)
把结果赋值给c
实现同样功能的Python代码如下
a = 1
b = 2
c = a + b
解释器只知道1和2是对象,但是并不知道这个对象的类型。所以解释器必须检查每个变量的PyObject_HEAD才能知道变量类型,然后执行对应的相加操作,最后要创建一个新的Python对象来保存返回值,大致流程如下:
把1赋值给a
设置a-》PyObject_HEAD-》typecode为整型
设置a-》val = 1
把2赋值给b
设置a-》PyObject_HEAD-》typecode为整型
设置b-》val = 2
调用binary_add《int, int》(a, b)
a-》PyObject_HEAD获取类型编码
a是一个整型;值为a-》val
b-》PyObject_HEAD获取类型编码
b是一个整型,值为b-》val
调用binary_add《int, int》(a-》val, b-》val)
结果为整型,存在result中
创建对象c
设c-》PyObject_HEAD-》typecode为整型
设置c-》val为result
动态类型意味着任何操作都会涉及更多的步骤。这是Python对数值操作比C语言慢的主要原因
Python是解释型语言
上面介绍了解释型代码和编译型代码的一个区别。智能的编译器可以提前预见并优化重复或不需要的操作,这会带来性能的提升。编译器是一个大的话题,这里不会展开。
Python的对象模型会带来低效的内存访问
和C语言的整数对比时,我们指出了Python多了额外一层信息。现在来看看数组的情况。在Python中我们可以使用标准库中提供的List对象;而在C语言中我们会使用基于缓冲区的数组。
最简单的NumPy数组是围绕C数据构建的Python对象,也就是说它有一个指向连续数据缓存区的指针。而Python的list具有指向连续的指针缓冲区的指针,这些指针每个都指向一个Python对象,结合上面的例子,这些Python对象是一个整数对象。这个结构像下面这样
很容易看出,如果你正在执行按顺序逐步完成数据的操作,numpy的内存布局比Python的内存布局更为高效,无论是存储成本还是访问的时间成本。
为什么使用Python
鉴于Python天生的低效率,我们为什么还要使用Python呢?种种理由大致可以归结为:动态类型使得Python比C更容易使用。Python非常的灵活和宽容,这种灵活性可以有效地利用开发时间,并且在那些确实需要C和Fortran优化的场合,Python可以轻松链接到已编译的库中。这也是Python在科学社区的使用率不断增长的原因。经提到了一些结论性的东西,下面我们用Python的一些工具来做一些验证。
下面的实验使用到了python, ipython, numpy,版本信息如下:
python:3.6.5
1.13.3
In : import sys
In : import numpy
In
Out: ’3.6.5’
In : numpy.__version__
Out: ’1.13.3’
本次实验使用机器64位的机器,如果是32位的机器话,下面提到的一些struct可能会有所不同。
整数
Python的整数使用起来非常简单。
In : x = 42
In : print(x)
42
接口的简单性掩盖了底层的复杂。在之前的内容里有提到过Python整数的内存布局。现在我们使用Python内置的ctypes模块来自省整数类型,前提是需要知道在C API中Python整数类型的定义。
在CPython中,变量x存储在一个名为_longobject的struct中,源码见Include/longintrepr.h
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit;
}
其中PyObject_VAR_HEAD是一个宏,在Include/object.h中定义的结构如下
typedef struct {
PyObject ob_base;
Py_ssize_t ob_size;
} PyVarObject;
其中PyObject在Include/object.h中定义如下
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
}
其中_PyObject_HEAD_EXTRA是一个在Python版本中通常不使用的宏。
将上面的信息结合起来,可以得到下面的结构
struct _longobject {
long ob_refcnt;
PyTypeObject *ob_type;
size_t ob_size;
long ob_digit;
}
这里面ob_refcnt变量是对象的引用计数,ob_type是指向包含该对象所有类型信息和方法定义的结构的指针,ob_digit保存实际的数值。
有了上面的知识,可以开始使用ctypes模块来观察时间的对象结构并提取上面的信息。
现在来用Python定义一个C的struct
In : import ctypes
In : class IntStruct(ctypes.Structure):
...: _fields_ = [
...: ("ob_refcnt", ctypes.c_long),
...: ("ob_type", ctypes.c_void_p),
...: ("ob_size", ctypes.c_ulong),
...: ("ob_digit", ctypes.c_long)
...: ]
...:
...: def __repr__(self):
...: return (
...: "IntStruct(ob_digit)={self.ob_digit}, refcount={self.ob_refcnt}"
...: ).format(self=self)
...:
现在用42来做实验。在Python中,id方法会返回对象的内存地址:
In : num = 42
In : IntStruct.from_address(id(42))
Out: IntStruct(ob_digit)=42, refcount=61
可以看到ob_digit指向了内存中的正确位置。但是这里只创建了一个对象,为什么引用次数是61呢?
事实证明,这是一个性能优化,Python使用了很多小的整数,如果为每一个数字都创建一个PyObject,会消耗掉不少内存。出于这个考虑,Python将一些常用的数字做了单例实现,这样每个数字在内存中只有一份拷贝。换句话说,如果在这个范围内创建一个新的Python整数时,只是创建了一个对该数值对象的引用。
In : x = 42
In : y = 42
In : id(x) == id(y)
Out: True
上面的例子中,x和y都指向了同一个内存地址。在使用更大的数的时候,等式就不成立了
In : x = 1234
In : y = 1234
In : id(x) == id(y)
Out: False
Python解释器启动时候会创建很多的整数对象;可以看看这些对象的引用分布
%matplotlib osx
import matplotlib.pyplot as plt
import sys
plt.loglog(range(1000), )
plt.xlabel(’integer value’)
plt.ylabel(’reference count’)
Out: Text(0,0.5,’reference count’)
可以看到0被引用了数千次,一般情况下,引用的频率随着整数值的增加而减少。
再来看看ob_digit对应的值
In : all(i == IntStruct.from_address(id(i)).ob_digit for i in range(256))
Out: True
如果更细心一点,就可以发现,对于大于256的值,ob_digit就不能对应到正确的值了:在Objects/longobject.c中对数值有一些移位操作,这也是Python对一些大整数的处理方式。
比如
In : 2 ** 100
Out: 1267650600228229401496703205376
这个值显然是超过了long类型的范围了。
List类型
现在来看看一个更复杂的数据类型:List。同样能在Include/listobject.h中找到List类型的struct结构:
typedef struct {
PyObject_VAR_HEAD
PyObject **ob_item;
Py_ssize_t allocated;
} PyListObject;
和之前一样,得到有效的结构体如下:
typedef struct {
long ob_refcnt;
PyTypeObject *ob_type;
Py_ssize_t ob_size;
PyObject **ob_item;
long allocated;
} PyListObject;
其中PyObject **ob_item指向list的数据,ob_size指出list中数据的个数。
In : class ListStruct(ctypes.Structure):
...: _fields_ = [("ob_refcnt", ctypes.c_long),
...: ("ob_type", ctypes.c_void_p),
...: ("ob_size", ctypes.c_ulong),
...: ("ob_item", ctypes.c_long), # PyObject** pointer cast t
...: o long
...: ("allocated", ctypes.c_ulong)]
...:
...: def __repr__(self):
...: return ("ListStruct(len={self.ob_size}, "
...: "refcount={self.ob_refcnt})").format(self=self)
试验一下
In
In : ListStruct.from_address(id(L))
Out: ListStruct(len=4, refcount=1)
为确保得到的结果是正确的,对这个list增加几个引用,看看会不会影响引用计数:
In
In : ListStruct.from_address(id(L))
Out: ListStruct(len=4, refcount=3)
使用ctypes可以创建由之前IntStruct对象组成的复合结构
In : Lstruct = ListStruct.from_address(id(L))
In : PtrArray = Lstruct.ob_size * ctypes.POINTER(IntStruct)
In : L_values = PtrArray.from_address(Lstruct.ob_item)
看看每个元素的值
In
Out:
[IntStruct(ob_digit=1, refcount=4705),
IntStruct(ob_digit=2, refcount=1102),
IntStruct(ob_digit=3, refcount=559),
IntStruct(ob_digit=4, refcount=726)]
NumPy的数组
同样的,我们来看看numpy中的数组。其C-API定义的结构见numpy/core/include/numpy/ndarraytypes.h,这里用的numpy版本是1.13.3,不同版本的结构可能有所不同。
In : np.__version__
Out: ’1.13.3’
现在用ctypes来创建一个numpy数组的结构吧。
In : class NumpyStruct(ctypes.Structure):
...: _fields_ = [("ob_refcnt", ctypes.c_long),
...: ("ob_type", ctypes.c_void_p),
...: ("ob_data", ctypes.c_long), # char* pointer cast to long
...: ("ob_ndim", ctypes.c_int),
...: ("ob_shape", ctypes.c_voidp),
...: ("ob_strides", ctypes.c_voidp)]
...:
...: @property
...: def shape(self):
...: return tuple((self.ob_ndim * ctypes.c_int64).from_address(self.ob_shape))
...:
...: @property
...: def strides(self):
...: return tuple((self.ob_ndim * ctypes.c_int64).from_address(self.ob_strides))
...:
...: def __repr__(self):
...: return ("NumpyStruct(shape={self.shape}, "
...: "refcount={self.ob_refcnt})").format(self=self)
新建一个numpy数组试试In : NumpyStruct(shape=(10, 20), refcount=1)
可以看到已经拿到了正确的shape。现在看看引用计数的情况
In
In : xstruct
Out: NumpyStruct(shape=(10, 20), refcount=4)
现在可以看看里面的数据了。
In : x = np.arange(10)
In : xstruct = NumpyStruct.from_address(id(x))
In : size = np.prod(xstruct.shape)
In : arraytype = size * ctypes.c_long
In : data = arraytype.from_address(xstruct.ob_data)
In
Out
上面的data变量存储了Numpy数组中定义的连续的内存块,可以改一下其中的值。
In = 555
In
Out
上面的例子可以证明x和data指向了同一块连续内存。
比较Python的list和numpy的ndarray的内部结构,明显可以看出numpy的数据对于表示同类型的数据列表来说简单的多。
结语
Python很慢,正如上面所说,一个重要原因是类型的间接寻址,这也是Python对开发者友好的原因。同时,Python本身也提供了可用于破解Python对象的工具,通过使用这些工具可以解析CPython的一些内部行为。
上

Numpy死活装不上是怎么回事

我估计你用的是Windows,虽然很多人推荐你用Enthought和Anaconda但是那个会剥夺你很多学习体验。如果你知道怎么用CMD/Powershell的话,先把Python的文件夹下面的l/ib文件夹放到你的系统变量里面去,另外就是选择安装Python 2.7.9这样pip是自带的。(如果这个你不会你还是用Pre-installed IDE吧)你在cmd里面用pip安装64位系统的numpy是会出现问题的,这个很多人都遇到过,而且之后估计你还要安装Scipy,这需要用到C和Fortran的编译器你估计也没有……
所以我建议你安装wheel文件,我给你一个地址lfd.uci.edu/~gohlke/pythonlibs/#numpy
看清楚根据你的python版本和你电脑的bit数来选择wheel文件。为了能够安装wheel文件,你需要首先安装wheel这个包。进到cmd里面输入pip install wheel
安装成功以后下载相应的numpy的wheel文件,在cmd里面移动到本地文件存放的地方。然后输入pip install numpy‑1.9.2+mkl‑cp27‑none‑win_amd64.whl
上面这个语句最后一部分是文件名,根据你问题的描述你应该就是下载这个文件,然后回车就可以自动安装了。你安装numpy+mkl的好处是会减少你安装scipy的阻力,安装scipy一直就不是一件惬意的事情。
当然了,如果你根本不想要这么麻烦,还是安装个Enthought, Anaconda或者PythonXY吧。

win 8 python2.7 用pip下载 nump 总是出现问题

貌似是提示文件名不对,下面是当前最新的numpy版本,对比一下看吧

***隐藏网址***

文章分享结束,numpy下载太慢和为啥我的Python这么慢的答案你都知道了吗?欢迎再次光临本站哦!

numpy下载太慢(为啥我的Python这么慢)

本文编辑:admin

更多文章:


圆梦巨人电影经典台词?电影圆梦巨人经典台词

圆梦巨人电影经典台词?电影圆梦巨人经典台词

本篇文章给大家谈谈织梦圆梦,以及圆梦巨人电影经典台词对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。

2026年10月11日 17:50

嵌入式软件开发工程师招聘(嵌入式工程师是干嘛的)

嵌入式软件开发工程师招聘(嵌入式工程师是干嘛的)

各位老铁们好,相信很多人对嵌入式软件开发工程师招聘都不是特别的了解,因此呢,今天就来为大家分享下关于嵌入式软件开发工程师招聘以及嵌入式工程师是干嘛的的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!

2026年10月11日 12:20

怎么做网站网页归档(网页应该怎么做网页设计有哪些要求)

怎么做网站网页归档(网页应该怎么做网页设计有哪些要求)

大家好,怎么做网站网页归档相信很多的网友都不是很明白,包括网页应该怎么做网页设计有哪些要求也是一样,不过没有关系,接下来就来为大家分享关于怎么做网站网页归档和网页应该怎么做网页设计有哪些要求的一些知识点,大家可以关注收藏,免得下次来找不到哦

2026年10月11日 05:30

跷二郎腿太低好吗?想要通过贴墙站改正二郎腿影响的话,有哪些要点需要注意

跷二郎腿太低好吗?想要通过贴墙站改正二郎腿影响的话,有哪些要点需要注意

本篇文章给大家谈谈二郎腿贴地,以及跷二郎腿太低好吗对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。

2026年10月11日 05:10

易语言点击js按钮(易语言网页填表怎样点击链接为“javascript:void(0)“的按钮)

易语言点击js按钮(易语言网页填表怎样点击链接为“javascript:void(0)“的按钮)

本篇文章给大家谈谈易语言点击js按钮,以及易语言网页填表怎样点击链接为“javascript:void(0)“的按钮对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要

2026年10月11日 03:00

regards(Regards,什么意思)

regards(Regards,什么意思)

其实regards的问题并不复杂,但是又很多的朋友都不太了解Regards,什么意思,因此呢,今天小编就来为大家分享regards的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!

2026年10月11日 01:10

dom4j文档(如何去掉用dom4j生成的XML文档中的)

dom4j文档(如何去掉用dom4j生成的XML文档中的)

其实dom4j文档的问题并不复杂,但是又很多的朋友都不太了解如何去掉用dom4j生成的XML文档中的,因此呢,今天小编就来为大家分享dom4j文档的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!

2026年10月11日 01:00

compare with造句(用compared with和compared to造句)

compare with造句(用compared with和compared to造句)

“compare with造句”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看compare with造句(用compared with和compared to造句)!

2026年10月10日 23:30

xshell软件(Xshell怎么更改字体大小)

xshell软件(Xshell怎么更改字体大小)

各位老铁们好,相信很多人对xshell软件都不是特别的了解,因此呢,今天就来为大家分享下关于xshell软件以及Xshell怎么更改字体大小的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!

2026年10月10日 22:50

tensorflow与keras对应版本(为什么tensorflow2.8没有keras)

tensorflow与keras对应版本(为什么tensorflow2.8没有keras)

各位老铁们好,相信很多人对tensorflow与keras对应版本都不是特别的了解,因此呢,今天就来为大家分享下关于tensorflow与keras对应版本以及为什么tensorflow2.8没有keras的问题知识,还望可以帮助大家,解决

2026年10月10日 22:10

最近更新

热门文章

by网站域名444(444ppp现在是什么域名)
2026-08-19 20:20:31 浏览:13
韩国大片视频mv(韩国20个感人mv)
2026-07-11 13:10:02 浏览:12
标签列表