日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

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

發布時間:2024/7/23 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python numpy和pandas库的区别_python – 来自熊猫和numpy的意思不同 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡潔版本:

之所以不同,是因為在調用平均操作時,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的意思不同的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。