Concatenar los caracteres individuales en los textos

Concatenar los caracteres individuales en los textos

Tengo una lista con nombres de empresas, algunas de ellas tienen abreviaturas. ej.:

compNames = ['Costa Limited', 'D B M LTD']

Necesito convertir compNames de texto en una matriz de conteos de tokens usando lo siguiente. Pero esto no genera columnas para B D M en D B M LTD

count_vect = CountVectorizer(analyzer='word')
count_vect.fit_transform(compNames).toarray()

¿Cuál es la mejor manera de concatenar los caracteres individuales en un texto?

ex: 'D B M LTD' to 'DBM LTD'
Mostrar la mejor respuesta

No entiendo cuál es el criterio para la decisión de concatenar o no. ¿Cómo decide que D, B, M deben concatenarse con DBM, pero LTD debe permanecer apartado. Quiero decir, en este ejemplo concreto, podría ser semánticamente obvio, pero para generar un algoritmo, debe haber un criterio general que funcione para todas las entradas de la manera deseada...

El algoritmo debe concatenar solo los caracteres individuales (B D M) pero no las palabras (LTD).

Lo siento, no estoy seguro de lo que quieres decir @anothernode. Tengo millones o nombres de empresas en esta lista y necesito concatenar caracteres individuales en cada nombre de empresa de la lista. Ese es un criterio general que necesito.

Creo que se refieren a cualquier carácter individual (no al lado de los que no están en blanco).

Muy bien, ahora lo entiendo.

Tienes razón @ArndtJonasson

import re
string = 'D B M LTD'
print re.sub("([^ ]) ", r"\1", re.sub(" ([^ ]{2,})", r"  \1", string))

Incómodo, pero debería funcionar. Introduce un espacio adicional delante de LTD y luego reemplaza "D" con "D", "B" con "B" y así sucesivamente.

¿Por qué dijiste que es 'incómodo'? Esto parece que funciona bien. ¿Alguna deficiencia?

Un error: re.sub("([^ ]) ", r"\1", re.sub(" ([^ ]{2,})", r" \1", "ffdjk g")) -> "ffdjkg"

@Shana porque usa sub dos veces

Aquí hay una función corta que divide una cadena en caracteres de espacio en blanco en una lista, itera la lista, crea una cadena temporal si el elemento tiene una longitud de 1, agrega la cadena temporal a una nueva lista cuando un elemento con una longitud mayor de lo que uno se encuentra.

import re

a = 'D B M LTD'

def single_concat(s):
    out = []
    tmp = ''
    for x in re.split(r'\s+', s):
        if len(x) == 1:
            tmp += x
        else:
            if tmp:
                out.append(tmp)
            out.append(x)
            tmp = ''
    return ' '.join(out)

single_concat(a)
# returns:
'DBM LTD'

No creo que realmente necesites re para hacer un split()... Me di cuenta de esto después de escribir esencialmente el mismo algoritmo :-)

import re

s = "D B M LTD"

first_part = ''
for chunk in re.compile("([A-Z]{1})\s").split(s):
    if len(chunk) == 1:
        first_part += chunk
    elif len(chunk) > 1:
        last_part = chunk

print(first_part + " " + last_part)

Imprime DBM LTD.

import re
string = 'D B M LTD'
print re.sub(r"\+", r"", re.sub(r"\+(\w\B)", r" \1", re.sub(r"(\b\w) ", r"\1+", string)))

Estoy usando el carácter + como temporal, asumiendo que no hay caracteres + en la cadena. Si las hay, utiliza alguna otra que no se dé.

Mira, no re:

def mingle(s):
    """ SO: 49692941 """
    l = s.split()
    r = []
    t = []
    for e in l:
        if len(e) == 1:
            t.append(e)
        else:
            j = "".join(t)
            r.append( j )
            r.append( e )
            t = []

    return " ".join(r)

print( mingle('D B M LTD') )

impresiones

DBM LTD