Python 如何在一次迭代中对numpy字符串数组进行多个函数调用?

Python 如何在一次迭代中对numpy字符串数组进行多个函数调用?,python,arrays,python-3.x,numpy,time-complexity,Python,Arrays,Python 3.x,Numpy,Time Complexity,代码如下: >>> import numpy as np >>> words = np.array([' woRd ', ' amaZINg ', ' PossiblE ']) >>> words_fixed = np.char.lower(np.char.strip(words)) >>> words_fixed array(['word', 'amazing', 'possible'], dtype='

代码如下:

>>> import numpy as np
>>> words = np.array(['   woRd ', '  amaZINg  ', '   PossiblE    '])
>>> words_fixed = np.char.lower(np.char.strip(words))
>>> words_fixed
array(['word', 'amazing', 'possible'], dtype='<U15')
很好用

根据我的理解,这段代码的复杂度为O2n,因为它首先在所有元素上调用strip,返回一个新的numpy数组,然后在该数组的所有元素上调用lower并返回另一个numpy数组。 现在,我知道O2n最终是开启的,但它能在复杂度上完成吗

有没有一种方法可以将多个函数调用堆叠起来,并在一次迭代中全部调用它们


当然,我不希望使用python循环,因为这首先会破坏使用numpy的全部目的。

单词列表和等效数组:

In [153]: words = ['   woRd ', '  amaZINg  ', '   PossiblE    ']                         
In [154]: arr = np.array(words)                                                          
您对阵列的操作:

In [155]: np.char.lower(np.char.strip(arr))                                              
Out[155]: array(['word', 'amazing', 'possible'], dtype='<U15')
或者在理解中使用生成器:

In [156]: [word.strip().lower() for word in words]                                         
Out[156]: ['word', 'amazing', 'possible']
In [159]: [word.lower() for word in (word.strip() for word in words)]                        
Out[159]: ['word', 'amazing', 'possible']
一些时间安排:

In [160]: timeit [word.lower() for word in (word.strip() for word in words)]
1.33 µs ± 10.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [161]: timeit [word.strip().lower() for word in words]                                  
848 ns ± 13.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [162]: timeit np.char.lower(np.char.strip(arr))                                       
12.3 µs ± 143 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
列表理解最快。有时numpy操作的扩展性更好,但根据过去使用np.char函数的经验,我认为这种情况不会在这里发生。np.char函数是Python字符串方法的简单封面

好的,有一种方法可以在字符串上调用两个python方法并在numpy中迭代:

因为它的时间是链式np.char的一半,所以可以说它将时间复杂度从2n降低到了n


只有在使用相同的迭代方法时,计数才有意义。使用Python/numpy使用的解释代码和编译代码的混合,以有限值计数。更重要的是优化使用更快的编译代码。

np.vectorize应该可以工作。您的阵列是否太大,需要对其进行优化?我的意思是,你可能有足够的内存来保存其中的两个数组。因为你似乎在抱怨空间的复杂性,因为时间的复杂性不会改变。时间的复杂性是我这里的主要问题。你能用代码写一个答案吗?我对numpy不太在行。如果有效的话,我会接受的。时间复杂度在这两种情况下都会出现。您不会在这方面有所改进,因为无论是在一个循环还是两个循环中执行,您仍然需要运行两个操作。@JBernardo,np.vectorize比普通Python迭代慢。np.char函数也没有更快。除非您编写lower+strip函数,否则我不确定是否可以提高先在单词上执行它们而不是先在数组上执行它们的时间复杂度。可能是因为从内存中读取,但lowerstrip仍然是每个单词上的两个操作。我尝试了30000个单词中的元素,事实上,[word.strip.lower for words in words]是最快的。我认为,使用像np.char这样的numpy代码会更快,因为numpy是用C编写的,比python快得多。
In [164]: np.frompyfunc(lambda word: word.strip().lower(),1,1)(arr)                        
Out[164]: array(['word', 'amazing', 'possible'], dtype=object)
In [165]: timeit np.frompyfunc(lambda word: word.strip().lower(),1,1)(arr)                 
6.87 µs ± 14.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)