Строковые функции Python не работают для столбца с объектом типа данных - PullRequest
2 голосов
/ 07 июля 2019

Я создал фрейм данных panda и пытаюсь разделить один из столбцов (dtype = object) на несколько столбцов с помощью разделителя.

Я пытался:

new = df["contract"].str.split(",", n=100, expand=True)

df[['Test2', 'conID', 'Test1', 'Expiration', 'Strike', 'Type', 'Multiplier', 'Exchange', 'Currency', 'Code', 'tradingClass']] = pd.DataFrame(df['contract'].tolist(), index=df.index)
df['contract_new'] = df['contract'].str.split(',') 
df['contract_new'] = df['contract'].astype('str')  
df['contract_new'] = df['contract'].str.replace('(', ',')

Ниже я скопировал в первые три строки содержимое столбца panda df с заголовком 'contract'. Это длинное поле с 10 важными точками данных, которые мне нужно указать в разных столбцах. Фрейм данных извлекается из API Interactive Brokers.

    contract                                                                                                                                                                                                                
0   Option(conId=357974235, symbol='SPX', lastTradeDateOrContractMonth='20190718', strike=2980.0, right='P', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPX   190719P02980000', tradingClass='SPX')   
1   Option(conId=357974238, symbol='SPX', lastTradeDateOrContractMonth='20190718', strike=2985.0, right='P', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPX   190719P02985000', tradingClass='SPX')   
2   Option(conId=357974242, symbol='SPX', lastTradeDateOrContractMonth='20190718', strike=2990.0, right='P', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPX   190719P02990000', tradingClass='SPX')   

Я хотел бы разделить столбец с 10 строками, разделенными запятой, на 10 отдельных столбцов или выполнить другие действия на основе строк. В конце я хочу увидеть следующие элементы в разных столбцах:

-SPX
-201907192980.0
-P 
-100 
-SMART
-USD
-190719P02980000 (THIS IS THE MOST IMPORTANT PART I NEED)
-SPX

Пока ничего не работает.

Ответы [ 3 ]

1 голос
/ 07 июля 2019

Это можно сделать без регулярных выражений, выполнив следующие манипуляции со строками (или что-то подобное) с данными в каждой строке.Используя первую строку в качестве примера:

option = "conId=357974235, symbol='SPX', lastTradeDateOrContractMonth='20190718', strike=2980.0, right='P', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPX   190719P02980000', tradingClass='SPX'"  

data = option.split(',')
to_delete = 0,3  #since apparently you aren't interested in 'conId' and 'strike'
for i in sorted(to_delete, reverse=True):
    del data[i]

for datum in data:
    if "localSymbol" in datum:
        datum = datum.replace('SPX   ','')
    print(datum.split('=')[1])

Вывод:

'SPX'
'20190718'
'P'
'100'
'SMART'
'USD'
'190719P02980000'
'SPX'

Чтобы автоматизировать процесс, давайте предположим, что данные хранятся так:

option1 = "conId=357974235, symbol='SPX', lastTradeDateOrContractMonth='20190718', strike=2980.0, right='P', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPX   190719P02980000', tradingClass='SPX'"  

option2 = "conId=357974238, symbol='SPX', lastTradeDateOrContractMonth='20190718', strike=2985.0, right='P', multiplier='100', exchange='SMART', currency='USD', localSymbol='SPX   190719P02985000', tradingClass='SPX'"

так далее.Код выше затем изменяется следующим образом:

options = [option1, option2] #etc.

option_data = [] #this is a list of lists which will host all relevant data
to_delete = 0,3

for option in options:
    data = option.split(',')    
    for i in sorted(to_delete, reverse=True):
        del data[i]
    current_datum = [] #this is a one time list that will store data for the current item
    for datum in data:            
        if "localSymbol" in datum:
            datum = datum.replace('SPX   ','')
        current_datum.append(datum.split('=')[1])
    option_data.append(current_datum)

Наконец, создайте фрейм данных:

columns = ['symbol','last trade','right','multiplier','exchange','currency','local symbol','trading class']

df = pd.DataFrame(option_data, columns =columns) 
df 

Вывод:

   symbol   last trade  right   multiplier  exchange    currency    local symbol    trading class
0   'SPX'   '20190718'  'P'     '100'   'SMART'     'USD'   '190719P02980000'   'SPX'
1   'SPX'   '20190718'  'P'     '100'   'SMART'     'USD'   '190719P02985000'   'SPX'
1 голос
/ 07 июля 2019

Я думаю, вы ищете что-то вроде этого:

def contract_to_columns(c):
  return pd.Series({"conId": c.conId, "symbol": c.symbol, "multiplier": c.multiplier, 
                    "lastTradeDateOrContractMonth": c.lastTradeDateOrContractMonth, 
                    "strike": c.strike, "right": c.right, "exchange": c.exchange, 
                    "currency": c.currency, "localSymbol": c.localSymbol.split()[1], 
                    "tradingClass": c.tradingClass})


df['contract'].apply(contract_to_columns)

вывод: enter image description here

ваш contract столбец является объектом, что вынужно сделать отображение объекта контракта на несколько столбцов, обратите внимание, что столбец localSymbol имеет префикс ( SPX ), который вам не нужен, я удалил его.Этот код зависит также от определения класса Option. Если вам нужна дополнительная помощь, поделитесь кодом класса Option.

Приветствия

1 голос
/ 07 июля 2019

Я только что обновил свой ответ. Я пытаюсь использовать операции с пандами, так как кажется, что у вас уже есть данные в кадре данных панд. Метод должен быть достаточно надежным в отношении отсутствующих пар ключ-значение и их порядка во входной строке:

import re
re_opt_start= re.compile('Option\(')
re_opt_end=   re.compile('\)\s*')
re_split=     re.compile('\s*,\s*')

df['contract']= df['contract'].str.replace(re_opt_start, '')
df['contract']= df['contract'].str.replace(re_opt_end, '')

df_split= df['contract'].str.split(',', expand=True)

result_df= None
for column in df_split:
    col_df= df_split[column].str.strip().str.split('=', expand=True)
    col_df.columns= ['col', 'value']
    col_df['value']= col_df['value'].str.strip("'")
    col_df.set_index('col', append=True, inplace=True)
    if result_df is None:
        result_df= col_df
    else:
        result_df= pd.concat([result_df, col_df], axis='index')

unstacked_df=result_df.unstack(level=-1).droplevel(0, axis='columns')
unstacked_df.loc[unstacked_df['localSymbol'].str[:3] == 'SPX', 'localSymbol']= unstacked_df['localSymbol'].str[3:]
unstacked_df

Возвращает:

Out[1285]: 
col      conId currency exchange lastTradeDateOrContractMonth  ... right  strike symbol tradingClass
0    357974235      USD    SMART                     20190718  ...     P  2980.0    SPX          SPX
1    357974238      USD    SMART                     20190718  ...     P  2985.0    SPX          SPX
2    357974242      USD    SMART                     20190718  ...     P  2990.0    SPX          SPX

[3 rows x 10 columns]
...