A critical portion of my script relies on the concatenation of a large number of fixed-length strings. So I would like to use low-level numpy.char.join function instead of the classical python build str.join.
However, I can't get it to work right:
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'))
.. and my initial array is always left unchanged.
What am I missing here?
What's numpy's most efficient way to concatenate each line of a large 2D <U1 array?
[EDIT]: Since performance is a concern, I have benchmarked proposed solutions. But I still don't know how to call np.char.join properly.
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]
)
outputs
41.722 seconds
19.921 seconds
15.206 seconds
on my machine.
Would np.char.join do better? How to make it work?