简洁版本:

之所以不同,是因为在调用平均操作时,pandas会使用瓶颈(如果已安装),而不是仅仅依赖于numpy.据推测,瓶颈似乎比numpy更快(至少在我的机器上),但代价是精确度.它们碰巧匹配64位版本,但32位不同(这是有趣的部分).

长版:

通过检查这些模块的源代码来判断发生了什么是非常困难的(它们非常复杂,即使是像平均值这样的简单计算,也很难说数值计算很难).最好使用调试器来避免大脑编译和那些类型的错误.调试器不会在逻辑上出错,它会告诉你究竟发生了什么.

这是我的一些堆栈跟踪(由于没有RNG的种子,值略有不同):

可以重现(Windows):

>>> import numpy as np; import pandas as pd

>>> x=np.random.normal(-9.,.005,size=900000)

>>> df=pd.DataFrame(x,dtype='float32',columns=['x'])

>>> df['x'].mean()

-9.0

>>> x.mean()

-9.0000037501099754

>>> x.astype(np.float32).mean()

-9.0000029

numpy的版本没什么特别的.这是熊猫版本有点古怪.

让我们来看看df [‘x’].mean():

>>> def test_it_2():

... import pdb; pdb.set_trace()

... df['x'].mean()

>>> test_it_2()

... # Some stepping/poking around that isn't important

(Pdb) l

2307

2308 if we have an ndarray as a value, then simply perform the operation,

2309 otherwise delegate to the object

2310

2311 """

2312 -> delegate = self._values

2313 if isinstance(delegate, np.ndarray):

2314 # Validate that 'axis' is consistent with Series's single axis.

2315 self._get_axis_number(axis)

2316 if numeric_only:

2317 raise NotImplementedError('Series.{0} does not implement '

(Pdb) delegate.dtype

dtype('float32')

(Pdb) l

2315 self._get_axis_number(axis)

2316 if numeric_only:

2317 raise NotImplementedError('Series.{0} does not implement '

2318 'numeric_only.'.format(name))

2319 with np.errstate(all='ignore'):

2320 -> return op(delegate, skipna=skipna, **kwds)

2321

2322 return delegate._reduce(op=op, name=name, axis=axis, skipna=skipna,

2323 numeric_only=numeric_only,

2324 filter_type=filter_type, **kwds)

所以我们找到了麻烦点,但现在事情变得有些奇怪了:

(Pdb) op

(Pdb) op(delegate)

-9.0

(Pdb) delegate_64 = delegate.astype(np.float64)

(Pdb) op(delegate_64)

-9.000003749978807

(Pdb) delegate.mean()

-9.0000029

(Pdb) delegate_64.mean()

-9.0000037499788075

(Pdb) np.nanmean(delegate, dtype=np.float64)

-9.0000037499788075

(Pdb) np.nanmean(delegate, dtype=np.float32)

-9.0000029

请注意,delegate.mean()和np.nanmean输出-9.0000029类型为float32,而不是-9.0作为pandas nanmean.稍微探讨一下,你可以在pandas.core.nanops中找到pandas nanmean的来源.有趣的是,它实际上似乎应该首先匹配numpy.我们来看看pandas nanmean:

(Pdb) import inspect

(Pdb) src = inspect.getsource(op).split("\n")

(Pdb) for line in src: print(line)

@disallow('M8')

@bottleneck_switch()

def nanmean(values, axis=None, skipna=True):

values, mask, dtype, dtype_max = _get_values(values, skipna, 0)

dtype_sum = dtype_max

dtype_count = np.float64

if is_integer_dtype(dtype) or is_timedelta64_dtype(dtype):

dtype_sum = np.float64

elif is_float_dtype(dtype):

dtype_sum = dtype

dtype_count = dtype

count = _get_counts(mask, axis, dtype=dtype_count)

the_sum = _ensure_numeric(values.sum(axis, dtype=dtype_sum))

if axis is not None and getattr(the_sum, 'ndim', False):

the_mean = the_sum / count

ct_mask = count == 0

if ct_mask.any():

the_mean[ct_mask] = np.nan

else:

the_mean = the_sum / count if count > 0 else np.nan

return _wrap_results(the_mean, dtype)

这是bottleneck_switch装饰器的(短)版本:

import bottleneck as bn

...

class bottleneck_switch(object):

def __init__(self, **kwargs):

self.kwargs = kwargs

def __call__(self, alt):

bn_name = alt.__name__

try:

bn_func = getattr(bn, bn_name)

except (AttributeError, NameError): # pragma: no cover

bn_func = None

...

if (_USE_BOTTLENECK and skipna and

_bn_ok_dtype(values.dtype, bn_name)):

result = bn_func(values, axis=axis, **kwds)

用alt作为pandas nanmean函数调用它,所以bn_name是’nanmean’,这是从瓶颈模块中获取的attr:

(Pdb) l

93 result = np.empty(result_shape)

94 result.fill(0)

95 return result

96

97 if (_USE_BOTTLENECK and skipna and

98 -> _bn_ok_dtype(values.dtype, bn_name)):

99 result = bn_func(values, axis=axis, **kwds)

100

101 # prefer to treat inf/-inf as NA, but must compute the fun

102 # twice :(

103 if _has_infs(result):

(Pdb) n

> d:\anaconda3\lib\site-packages\pandas\core\nanops.py(99)f()

-> result = bn_func(values, axis=axis, **kwds)

(Pdb) alt

(Pdb) alt.__name__

'nanmean'

(Pdb) bn_func

(Pdb) bn_name

'nanmean'

(Pdb) bn_func(values, axis=axis, **kwds)

-9.0

假装bottleneck_switch()装饰器暂时不存在.我们实际上可以看到调用手动单步执行此函数(没有瓶颈)将获得与numpy相同的结果:

(Pdb) from pandas.core.nanops import _get_counts

(Pdb) from pandas.core.nanops import _get_values

(Pdb) from pandas.core.nanops import _ensure_numeric

(Pdb) values, mask, dtype, dtype_max = _get_values(delegate, skipna=skipna)

(Pdb) count = _get_counts(mask, axis=None, dtype=dtype)

(Pdb) count

900000.0

(Pdb) values.sum(axis=None, dtype=dtype) / count

-9.0000029

但是,如果你已经安装了瓶颈,那就永远不会被调用.相反,bottleneck_switch()装饰器反而突破了nanmean函数和瓶颈版本.这就是差异所在(有趣的是它在float64的情况下是匹配的):

(Pdb) import bottleneck as bn

(Pdb) bn.nanmean(delegate)

-9.0

(Pdb) bn.nanmean(delegate.astype(np.float64))

-9.000003749978807

据我所知,瓶颈仅用于速度.我假设他们正在使用他们的nanmean函数采用某种类型的快捷方式,但我没有对它进行过多考察(有关此主题的详细信息,请参阅@ ead的答案).您可以看到它的基准测试通常比numpy快一点:https://github.com/kwgoodman/bottleneck.显然,为这个速度付出的代价是精确的.

瓶颈实际上更快吗?

当然看起来像(至少在我的机器上).

In [1]: import numpy as np; import pandas as pd

In [2]: x=np.random.normal(-9.8,.05,size=900000)

In [3]: y_32 = x.astype(np.float32)

In [13]: %timeit np.nanmean(y_32)

100 loops, best of 3: 5.72 ms per loop

In [14]: %timeit bn.nanmean(y_32)

1000 loops, best of 3: 854 ?s per loop

对于pandas来说,在这里引入一个标志可能会很好(一个用于速度,另一个用于更好的精度,默认用于速度,因为那是当前的impl).一些用户更关心计算的准确性而不是它发生的速度.

HTH.

python numpy和pandas库的区别_python – 来自熊猫和numpy的意思不同相关推荐

  1. python numpy和pandas库的区别_Python模块 - Numpy与Pandas

    Numpy简介 Numpy是高性能科学计算和数据分析的基础包.它是pandas等其他各种工具的基础. Numpy的主要功能: ndarray,一个多维数组结构,高效且节省空间 无需循环对数组数据进行快 ...

  2. Python数据分析笔记——Numpy、Pandas库

    Python数据分析--Numpy.Pandas库 总第48篇 ▼ 利用Python进行数据分析中有两个重要的库是Numpy和Pandas,本章将围绕这两个库进行展开介绍. Numpy库 Numpy最 ...

  3. 四、Python数据挖掘(Pandas库)

    四.Python数据挖掘(Pandas库) 目录: 四.Python数据挖掘(Pandas库) 一.Pandas 简介 二.Pandas 三大结构之--DataFrame 1.DataFrame 的创 ...

  4. Python数据分析之Pandas库

    Python数据分析之Pandas库 一.Pandas简介 二.Pandas库的安装 三.Pandas的数据结构 四.Series 和 DataFrame 数据结构的使用 五.其他可以参考的网站 一. ...

  5. Python强大的Pandas库—数据艺术家

    Python强大的Pandas库-数据艺术家 日期:2021/4/21 作者:就叫易易好了 pandas是Python中的一个库,是一个强大的分析结构化数据集. pandas中的常见的数据结构有两种: ...

  6. python对二维数组统计某一行的去重计数_Python数据分析笔记——Numpy、Pandas库

    利用Python进行数据分析中有两个重要的库是Numpy和Pandas,本章将围绕这两个库进行展开介绍. Numpy库 Numpy最重要的一个特点是就是其N维数组对象,即ndarray,ndarray ...

  7. ubuntu下python安装pandas和numpy等依赖库版本不兼容的问题RuntimeWarning: numpy.dtype size changed...

    习惯了linux下用pip install numpy及pip install pandas命令了.折腾了好久了. 上来先在python3中pip3 install numpy装了numpy,然后再p ...

  8. python怎么导入pandas库_Python之2-Pandas数据导入导出

    Pandas可以读取与存取像CSV\EXCEL\JSON\HTML\SQL数据库等格式的资料,具体如下: 一:从excel中读取数据并另存一张表 #读取excel中的数据 bill=pd.read_e ...

  9. python包和库的区别_python的库和包

    广告关闭 回望2020,你在技术之路上,有什么收获和成长么?对于未来,你有什么期待么?云+社区年度征文,各种定制好礼等你! python会把.zip归档文件当成一个目录去处理,1 #首先制作归档文件: ...

最新文章

  1. java tcp client断开重连_ESP8266_12 ESP8266客户端模式下的TCP通信
  2. 当下数据中心业务面临哪些重大威胁?
  3. 【安全】从mimikatz学习Windows安全之访问控制模型
  4. [C++] this指针
  5. oracle group by 多类别_python数据关系型图表散点图系列多数据系列
  6. SSE instruction set not enabled
  7. 20155302《网络对抗》Exp7 网络欺诈防范
  8. 【易实战】Spring Cloud微服务架构12要素应用 Twelve‑Factor App
  9. Ubuntu-区域截图
  10. 固定资产管理软件分析
  11. 什么是传统企业电商洪水围城下的诺亚方舟
  12. 关于微信小程序授权登陆之后需要在个人信息页展示信息,如微信头像,昵称这件事
  13. 【概率论】指数分布 Exponential Distribution
  14. 面向对象,数据库交互的Spring-boot(新手)
  15. 蛋糕瓜分殆尽 谁会成为下一个手游造富的加速器?
  16. 常见的HTTP状态码及HTTP状态码大全
  17. AIR32F103(九) CAN总线的通信和ID过滤机制及实例
  18. Java项目:公寓房屋出租系统(java+SSM+JSP+EasyUI+Echarts+Mysql)
  19. C++中类,对象,封装,继承(派生),多态
  20. 情人节程序员用HTML网页表白【七夕告白(520气球)】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript

热门文章

  1. 【计算机网络复习 物理层】2.1.5 编码与调制
  2. Leetcode--820:单词的压缩编码(java)
  3. php 判断不是文件类型,php 判断文件类型
  4. python 调用c++库接口出错
  5. 保存时间 默认_一些不起眼但又非常的实用的PPT制作技巧,大大节省PPT制作时间...
  6. python vba 秒出结果_为什么公司每天用20个人手工处理数据出报告,也不用5个会vba,python的人来制作??...
  7. r3 4300u r5 u_R5刀粒
  8. case when 多条件_3年前的设计如今被iPhone强推 PITAKA磁吸生态设计的前瞻性到底有多可怕?...
  9. Halcon算子学习:smooth_object_model_3d
  10. 计算机视觉三大顶级会议ICCV,CVPR,ECCV网址