栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

numpy矢量化弄乱了数据类型(2)

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

numpy矢量化弄乱了数据类型(2)

概要

如果使用,

np.vectorize
则最好指定
otypes
。在这种情况下,错误是由未指定
vectorize
使用时间的试验计算引起的
otypes
。另一种方法是将Series作为对象类型数组传递。

np.vectorize
有性能免责声明。
np.frompyfunc
可能更快,甚至可以理解列表。

测试 向量化

让我们定义一个更简单的函数-一个显示参数类型的函数:

In [31]: def foo(dt, excluded_months=[]):     ...:     print(dt,type(dt))     ...:     return True

还有一个较小的数据框:

In [32]: df = pd.Dataframe({'date': pd.date_range('2020-01-01', freq='7D', perio    ...: ds=5)})         In [33]: df   Out[33]:         date0 2020-01-011 2020-01-082 2020-01-153 2020-01-224 2020-01-29

测试

vectorize
。(
vectorize
docs说使用
excluded
参数会降低性能,所以我正在使用
lambda
with所使用的
apply
):

In [34]: np.vectorize(lambda x:foo(x,[3,8]))(df['date'])  2020-01-01T00:00:00.000000000 <class 'numpy.datetime64'>2020-01-01 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-08 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-15 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-22 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-29 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>Out[34]: array([ True,  True,  True,  True,  True])

第一行是

datetime64
产生问题的。其他行是原始的熊猫对象。如果指定
otypes
,该问题将消失:

In [35]: np.vectorize(lambda x:foo(x,[3,8]), otypes=['bool'])(df['date'])       2020-01-01 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-08 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-15 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-22 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-29 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>Out[35]: array([ True,  True,  True,  True,  True])

适用:

In [36]: df['date'].apply(lambda x: foo(x, [3, 8]))       2020-01-01 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-08 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-15 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-22 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-29 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>Out[36]: 0    True1    True2    True3    True4    TrueName: date, dtype: bool

datetime64
D型是通过在包裹的系列生产的
np.array

In [37]: np.array(df['date'])       Out[37]: array(['2020-01-01T00:00:00.000000000', '2020-01-08T00:00:00.000000000',       '2020-01-15T00:00:00.000000000', '2020-01-22T00:00:00.000000000',       '2020-01-29T00:00:00.000000000'], dtype='datetime64[ns]')

显然

np.vectorize
,在执行初始试验计算时会进行这种包装,但在进行主迭代时则不会。指定
otypes
跳过该试用计算。尽管这是一个比较模糊的情况,但是该试用计算在其他SO中引起了问题。

在过去,当我进行测试时,

np.vectorize
它比更明确的迭代要慢。它确实有明确的性能免责声明。当函数需要多个输入并需要广播的好处时,这是最有价值的。仅使用一个参数很难证明。

np.frompyfunc
underlies
vectorize
,但返回对象dtype。它的速度通常比数组上的显式迭代快2倍,尽管其速度与列表上的迭代速度相似。在创建和使用numpy对象数组时,它似乎最有用。在这种情况下,我没有使它起作用。

向量化代码

np.vectorize
代码是在
np.lib.function_base.py

如果

otypes
未指定,则代码执行以下操作:

        args = [asarray(arg) for arg in args]        inputs = [arg.flat[0] for arg in args]        outputs = func(*inputs)

它将每个参数(此处只有一个)放入一个数组,并采用第一个元素。然后将其传递给

func
。如图
Out[37]
所示,这将是一个
datetime64
对象。

frompyfunc

要使用

frompyfunc
,我需要转换的dtype
df['date']

In [68]: np.frompyfunc(lambda x:foo(x,[3,8]), 1,1)(df['date'])       1577836800000000000 <class 'int'>1578441600000000000 <class 'int'>...

没有它,它传递

int
给函数,并传递给熊猫时间对象:

In [69]: np.frompyfunc(lambda x:foo(x,[3,8]), 1,1)(df['date'].astype(object))   2020-01-01 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>2020-01-08 00:00:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>...

因此,这种使用方式

qualifies
是:

In [71]: np.frompyfunc(lambda x:qualifies(x,[3,8]),1,1)(df['date'].astype(object))   Out[71]: 0    False1     True2     True3     True4    FalseName: date, dtype: object

对象类型

对于主迭代,

np.vectorize

      ufunc = frompyfunc(_func, len(args), nout)      # Convert args to object arrays first        inputs = [array(a, copy=False, subok=True, dtype=object)       for a in args]        outputs = ufunc(*inputs)

这就解释了为什么

vectorize
可以
otypes
工作-它
frompyfunc
与对象dtype输入一起使用。将其与
Out[37]

In [74]: np.array(df['date'], dtype=object)    Out[74]: array([Timestamp('2020-01-01 00:00:00'), Timestamp('2020-01-08 00:00:00'),       Timestamp('2020-01-15 00:00:00'), Timestamp('2020-01-22 00:00:00'),       Timestamp('2020-01-29 00:00:00')], dtype=object)

另一种指定方法

otypes
是确保将dtype对象传递给
vectorize

In [75]: np.vectorize(qualifies, excluded=[1])(df['date'].astype(object), [3, 8])    Out[75]: array([False,  True,  True,  True, False])

这似乎是最快的版本:

np.frompyfunc(lambda x: qualifies(x,[3,8]),1,1)(np.array(df['date'],object))

或更好的是,一个简单的Python迭代:

[qualifies(x,[3,8]) for x in df['date']]


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/614282.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号