Как разбить строку по пробелам и списку слов - PullRequest
0 голосов
/ 03 октября 2019

Предположим, у меня есть строка ниже:

"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 = 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())

[ВЫХОД]

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]    

Я хочу сохранитьсписок составных слов

words_list = ["Notional Amount:","Fixed Rate Payer Currency Amount:","Fixed Rate Payer Payment Dates:"]

Я хочу разделить строку на строковый массив, как показано ниже:

["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"]

Когда я разделяю эту строку, я хотел бы сохранить некоторые слова какне всегда расщепляется по пространству. Кто-нибудь знает, как сделать этот вид разделения строк в Python? Есть мысли?

Ответы [ 4 ]

0 голосов
/ 03 октября 2019
 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))

[Вывод]

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]    

Я запрограммировал это с помощью Arkenys. Но есть ли более хорошие решения?

0 голосов
/ 03 октября 2019

Как сказал Ксхаттам, вероятно, нет никакого общего способа сделать свое дело.

Однако, предполагая, что вы знаете, какие строки с пробелами вы не хотите разбивать, вы можете сделать следующее (из вашего примера):

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

Теперь вы сможетенапечатайте my_list и получите следующий результат:

print(my_list)
['USD', 'Notional Amount:', 'USD', '50,000,000.00']

Это конкретный пример, который вы можете легко адаптировать к другим вашим строкам.

0 голосов
/ 03 октября 2019

Этот генератор должен выполнить трюк, хотя ':' будет извлечен из вывода. Возвращение будет кортежем. Все эти артефакты могут быть изменены в соответствии с вашим форматом:)

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:]
0 голосов
/ 03 октября 2019

Я не думаю, что есть общий способ сделать это, ваши сплиты могут сильно отличаться, поэтому я бы посоветовал потратить некоторое время на нормализацию вашего ввода вначале (например, поместить его вэлектронная таблица с одинаковым количеством столбцов для каждой строки) Это действительно упростит остальную часть вашего процесса). НО, вот способ сделать это с вашими данными.

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)

Это возвращает следующее, но работает только с вашей конкретной строкой. Вам нужно изменить то, что у вас там было больше элементов или, например, для разных валют (я кодировал только 'USD' в 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']
...