簡體   English   中英

numpy字符串分區:執行多個拆分

[英]Numpy String Partitioning: Perform Multiple Splits

我有一個字符串數組,每個字符串包含一個或多個單詞。 我想在分隔符(在我的情況下為空白)上對數組進行拆分/分區,該拆分與包含最多分隔符的元素中的分隔符一樣多。 但是,無論分隔符出現的頻率如何, numpy.char.partition僅執行一次拆分:

我有:

>>> a = np.array(['word', 'two words', 'and three words'])
>>> np.char.partition(a, ' ')

>>> array([['word', '', ''],
       ['two', ' ', 'words'],
       ['and', ' ', 'three words']], dtype='<U8')

我想擁有:

>>> array([['word', '', '', '', ''],
       ['two', ' ', 'words', '', ''],
       ['and', ' ', 'three', ' ', 'words']], dtype='<U8')

方法1

這些partition功能似乎並沒有對所有出現的事件進行分區。 為了解決我們的問題,我們可以使用np.char.split來獲取拆分字符串,然后使用maskingarray-assignment ,如下所示:

def partitions(a, sep):
    # Split based on sep
    s = np.char.split(a,sep)

    # Get concatenated split strings
    cs = np.concatenate(s)

    # Get params
    N = len(a)
    l = np.array(list(map(len,s)))
    el = 2*l-1
    ncols = el.max()

    out = np.zeros((N,ncols),dtype=cs.dtype)

    # Setup valid mask that starts at fist col until the end for each row
    mask = el[:,None] > np.arange(el.max())

    # Assign sepeter into valid ones
    out[mask] = sep

    # Setup valid mask that has True at postions where words are to be assigned
    mask[:,1::2] = 0

    # Assign words
    out[mask] = cs
    return out

樣品運行-

In [32]: a = np.array(['word', 'two words', 'and three words'])

In [33]: partitions(a, sep=' ')
Out[33]: 
array([['word', '', '', '', ''],
       ['two', ' ', 'words', '', ''],
       ['and', ' ', 'three', ' ', 'words']], dtype='<U5')

In [44]: partitions(a, sep='ord')
Out[44]: 
array([['w', 'ord', ''],
       ['two w', 'ord', 's'],
       ['and three w', 'ord', 's']], dtype='<U11')

方法#2

這是另一個循環,以節省內存-

def partitions_loopy(a, sep):
    # Get params
    N = len(a)
    l = np.char.count(a, sep)+1
    ncols = 2*l.max()-1
    out = np.zeros((N,ncols),dtype=a.dtype)
    for i,(a_i,L) in enumerate(zip(a,l)):
        ss = a_i.split(sep)
        out[i,1:2*L-1:2] = sep
        out[i,:2*L:2] = ss
    return out

我想出了自己的使用np.char.partition的遞歸解決方案。 但是,在對它進行計時時,結果表現不佳。 該時間類似於@Divakar針對單個拆分的解決方案,但隨后乘以所需的拆分次數。

def partitions(a, sep):
    if np.any(np.char.count(a, sep) >= 1):
        a2 = np.char.partition(a, sep)
        return np.concatenate([a2[:, 0:2], partitions(a2[:, 2], sep)], axis=1)
    return a.reshape(-1, 1)

基於函數的方法很棒,但看起來太復雜了。 您只需使用數據結構轉換和re.split 在單行代碼中即可解決此問題。

a = np.array(['word', 'two words', 'and three words'])

#Use the re.split to get partitions then transform to dataframe, fillna, transform back!

np.array(pd.DataFrame([re.split('( )', i) for i in a]).fillna(''))

#You can change the '( )' to '(\W)' if you want it to separate on all non-word characters!
array([['word', '', '', '', ''],
       ['two', ' ', 'words', '', ''],
       ['and', ' ', 'three', ' ', 'words']], dtype=object)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM