Supongamos que tengo debajo de la cadena:
"USD Notional Amount: USD 50,000,000.00"
"USD Fixed Rate Payer Currency Amount: USD 10,000,000"
"USD Fixed Rate Payer Payment Dates: Annually"
"KRW Fixed Rate Payer Payment Dates: Annually"
Simplemente, usando la función dividida
df = pd.DataFrame(["USD Notional Amount: USD 50,000,000.00"
,"USD Fixed Rate Payer Currency Amount: USD 10,000,000"
,"USD Fixed Rate Payer Payment Dates: Annually"
,"KRW Fixed Rate Payer Payment Dates: Annually"])
df[0].apply(lambda x: x.split())
[SALIDA]
0 [USD, Notional, Amount:, USD, 50,000,000.00]
1 [USD, Fixed, Rate, Payer, Currency, Amount:, USD, 10,000,000]
2 [USD, Fixed, Rate, Payer, Payment, Dates:, Annually]
3 [KRW, Fixed, Rate, Payer, Payment, Dates:, Annually]
Quiero conservar la lista de palabras compuestas
words_list = ["Notional Amount:","Fixed Rate Payer Currency Amount:","Fixed Rate Payer Payment Dates:"]
Lo que quiero es dividir la cadena en una matriz de cadenas, como a continuación:
["USD","Notional Amount:","USD", "50,000,000.00"]
["USD","Fixed Rate Payer Currency Amount:","USD","10,000,000"]
["USD","Fixed Rate Payer Payment Dates:","Annually"]
["KRW","Fixed Rate Payer Payment Dates:","Annually"]
Cuando divido esta cadena me gustaría conservar algunas palabras, ya que no siempre se divide por espacio. ¿Alguien sabe cómo hacer este tipo de división de cadenas en Python? ¿Alguna idea?
4 respuestas
Como dijo Xhattam, probablemente no haya una forma genérica de hacer lo suyo.
Sin embargo, suponiendo que sepa qué cadenas con espacios no desea dividir, puede hacer lo siguiente (a partir de su ejemplo):
test = "USD Notional Amount: USD 50,000,000.00"
a = ['Notional Amount:', 'Fixed Rate Payer Currency Amount:', 'Fixed Rate Payer Payment Dates:', 'Fixed Rate Payer Payment Dates:']
for element in a:
if element in test:
# Do this to strip your string from the list
my_list = test.replace(element, '')
# Do this to replace double space by simple space following the word stripping
my_list = test.replace(' ', ' ')
# Insert the element you striped in the list at the wanted index
my_list.insert(1, element)
break
Ahora debería poder imprimir my_list y obtener el siguiente resultado:
print(my_list)
['USD', 'Notional Amount:', 'USD', '50,000,000.00']
Este es un ejemplo específico que puede adaptar fácilmente a sus otras cadenas.
def split_emptynword(string_array):
for element in wordlist:
if element in string_array :
my_list = string_array.replace(element, 'Change').split()
my_list = [ element if x == 'Change' else x for x in my_list]
break
else:
my_list = string_array.split()
return my_list
df[0].apply(lambda x: split_emptynword(x))
[Salida]
0 [USD, Notional Amount:, USD, 50,000,000.00]
1 [USD, Fixed, Rate, Payer, Currency, Amount:, USD, 10,000,000]
2 [USD, Fixed Rate Payer Payment Dates:, Annually]
3 [KRW, Fixed Rate Payer Payment Dates:, Annually]
Codifiqué así, con la ayuda de Arkenys. ¿Pero más buenas soluciones?
No creo que haya una forma genérica de hacer esto, sus divisiones pueden variar demasiado, por lo que sugeriría pasar algo de tiempo en normalizar su entrada primero (por ejemplo, póngalo en una hoja de cálculo con el mismo número de columnas para cada línea) Esto realmente simplificaría el resto de su proceso). PERO, aquí hay una manera de hacerlo, con sus datos.
st = """USD Notional Amount: USD 50,000,000.00
USD Fixed Rate Payer Currency Amount: USD 10,000,000
USD Fixed Rate Payer Payment Dates: Annually
KRW Fixed Rate Payer Payment Dates: Annually"""
def split_stuff(st):
res = []
lines = st.split("\n") # splitting on carriage return
for line in lines:
currency, rest = line.split(" ", 1) # splitting on space, stopping after first space to extract currency (USD, KRW)
res.append([currency] + [e for e in deal_with_rest(rest)])
return res
def deal_with_rest(rest):
""" Deals with anything after the (first) currency """
compound, amt_type = rest.rsplit(" ", 1) # gets the compound and the amt value or type (here, 'annually')
if compound.strip().endswith("USD"): # if we see there's a currency again, we need to split on it one more time
return [e for e in compound.rsplit(" ", 1)] + [amt_type] # creating new sublist with compound, currency, and amount
else:
return [compound, amt_type] # otherwise, just returning the compound and the amount
for e in split_stuff(st):
print(e)
Esto devuelve lo siguiente, pero solo funciona con su cadena específica. Tendría que cambiar las cosas si tuviera más elementos allí, o para diferentes monedas, por ejemplo (solo codifiqué para 'USD' en deal_with_rest()
):
['USD', 'Notional Amount:', 'USD', '50,000,000.00']
['USD', 'Fixed Rate Payer Currency Amount:', 'USD', '10,000,000']
['USD', 'Fixed Rate Payer Payment Dates:', 'Annually']
['KRW', 'Fixed Rate Payer Payment Dates:', 'Annually']
Sin embargo, este generador debería hacer el truco, ':' se eliminará de la salida. El regreso será de tuplas. Todos esos artefactos se pueden cambiar para cumplir con su formato :)
import re
def string_to_accounting(string):
for line in string.split("\n"):
a, b = line.split(":")
if re.search("[A-Z]{3} ", b): # this could be more strikt if needed
yield a[:3], a[4:], b[1:4], b[5:]
else:
yield a[:3], a[4:], b[1:]
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.