gpt4 book ai didi

python - 如何使用 numpy.char.join?

转载 作者:行者123 更新时间:2023-12-04 14:15:07 27 4
gpt4 key购买 nike

我的脚本的一个关键部分依赖于大量固定长度字符串的串联。所以我想使用低级 numpy.char.join 函数而不是经典的 python 构建 str.join .

但是,我无法让它正常工作:

import numpy as np

# Example array.
array = np.array([
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i'],
], dtype='<U1')

# Now I wish to get:
# array(['abc', 'def', 'ghi'], dtype='<U3')

# But none of these is successful :(
np.char.join('', array)
np.char.join('', array.astype('<U3'))
np.char.join(np.array(''), array.astype('<U3'))
np.char.join(np.array('').astype('<U3'), array.astype('<U3'))
np.char.join(np.array(['', '', '']).astype('<U3'), array.astype('<U3'))
np.char.join(np.char.asarray(['', '', '']).astype('<U3'), np.char.asarray(array))
np.char.asarray(['', '', '']).join(array)
np.char.asarray(['', '', '']).astype('<U3').join(array.astype('<U3'))

.. 我的初始数组始终保持不变。

我在这里缺少什么?
numpy 连接大型二维的每一行的最有效方法是什么 <U1大批?

[编辑]:由于性能是一个问题,我对提议的解决方案进行了基准测试。但是我还是不知道怎么打电话 np.char.join 适本地。

import numpy as np
import numpy.random as rd
from string import ascii_lowercase as letters
from time import time

# Build up an array with many random letters
n_lines = int(1e7)
n_columns = 4
array = np.array(list(letters))[rd.randint(0, len(letters), n_lines * n_columns)]
array = array.reshape((n_lines, n_columns))

# One quick-n-dirty way to benchmark.
class MeasureTime(object):
def __enter__(self):
self.tic = time()
def __exit__(self, type, value, traceback):
toc = time()
print(f"{toc-self.tic:0.3f} seconds")


# And test three concatenations procedures.
with MeasureTime():
# Involves str.join
cat = np.apply_along_axis("".join, 1, array)

with MeasureTime():
# Involves str.join
cat = np.array(["".join(row) for row in array])

with MeasureTime():
# Involve low-level np functions instead.
# Here np.char.add for example.
cat = np.char.add(
np.char.add(np.char.add(array[:, 0], array[:, 1]), array[:, 2]), array[:, 3]
)

产出
41.722 seconds
19.921 seconds
15.206 seconds

在我的机器上。

np.char.join 做得更好?如何使它工作?

最佳答案

在原始 (3,3) 数组上(时间可能会有所不同):

链式 np.char.add :

In [88]: timeit np.char.add(np.char.add(arr[:,0],arr[:,1]),arr[:,2])                           
29 µs ± 223 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

一种等效的方法,使用 object数据类型。对于 python 字符串,'+' 是一个字符串连接。
In [89]: timeit arr.astype(object).sum(axis=1)                                                 
14.1 µs ± 18.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

对于字符串列表, ''.join()应该比字符串总和更快。此外,它还允许您指定“分隔符”:
In [90]: timeit np.array([''.join(row) for row in arr])                                        
13.8 µs ± 41.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

没有转换回数组:
In [91]: timeit [''.join(row) for row in arr]                                                      
10.2 µs ± 15.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

更好的是,使用 tolist将数组转换为字符串列表列表:
In [92]: timeit [''.join(row) for row in arr.tolist()]                                         
1.01 µs ± 1.81 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

列表理解等价于嵌套 np.char.add :
In [97]: timeit [row[0]+row[1]+row[2] for row in arr.tolist()]                                 
1.19 µs ± 2.68 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
numpy没有低级字符串代码,至少与它具有低级编译数字代码不同。它仍然依赖于 Python 字符串代码,即使它是从 C-API 调用的。

====

由于字符串是 U1 ,我们可以将它们视为 U3 :
In [106]: arr.view('U3')                                                                       
Out[106]:
array([['abc'],
['def'],
['ghi']], dtype='<U3')
In [107]: arr.view('U3').ravel()
Out[107]: array(['abc', 'def', 'ghi'], dtype='<U3')
In [108]: timeit arr.view('U3').ravel()
1.04 µs ± 9.81 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

===

使用 np.char.join我们必须将行收集到某种元组、列表等中。一种方法是创建一个对象 dtype 数组,并从数组中填充它:
In [110]: temp = np.empty(arr.shape[0], object)                                                
In [111]: temp
Out[111]: array([None, None, None], dtype=object)
In [112]: temp[:] = list(arr)
In [113]: temp
Out[113]:
array([array(['a', 'b', 'c'], dtype='<U1'),
array(['d', 'e', 'f'], dtype='<U1'),
array(['g', 'h', 'i'], dtype='<U1')], dtype=object)
In [114]: np.char.join('',temp)
Out[114]: array(['abc', 'def', 'ghi'], dtype='<U3')

或用列表列表填充它:
In [115]: temp[:] = arr.tolist()                                                               
In [116]: temp
Out[116]:
array([list(['a', 'b', 'c']), list(['d', 'e', 'f']),
list(['g', 'h', 'i'])], dtype=object)
In [117]: np.char.join('',temp)
Out[117]: array(['abc', 'def', 'ghi'], dtype='<U3')

In [122]: %%timeit
...: temp = np.empty(arr.shape[0], object)
...: temp[:] = arr.tolist()
...: np.char.join('', temp)
...:
...:
22.1 µs ± 69.1 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

====

为了更好地了解 np.char.join能做的,对比一下 split :
In [132]: temp                                                                                 
Out[132]:
array([list(['a', 'b', 'c']), list(['d', 'e', 'f']),
list(['g', 'h', 'i'])], dtype=object)
In [133]: b = np.char.join(',',temp)
In [134]: b
Out[134]: array(['a,b,c', 'd,e,f', 'g,h,i'], dtype='<U5')
In [135]: np.char.split(b,',')
Out[135]:
array([list(['a', 'b', 'c']), list(['d', 'e', 'f']),
list(['g', 'h', 'i'])], dtype=object)

另一种申请方式 ''.join到对象数组的元素:
In [136]: np.frompyfunc(lambda s: ','.join(s), 1,1)(temp)                                      
Out[136]: array(['a,b,c', 'd,e,f', 'g,h,i'], dtype=object)

关于python - 如何使用 numpy.char.join?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60954358/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com