Как создать несколько столбцов из значения столбца с помощью функций разделения

#python #pandas

Вопрос:

У меня есть столбец, в котором я хочу разделить значение столбца с помощью функции разделения. Имея имя столбца в качестве первого символа и значение столбца в качестве 2-го символа, разделенного на:

Входные данные

 Column1   Column2 

Item1    Material, Teflon ; MODEL: 28' Inches ; MAKE : SAMSUNG ; SUPPLIER/PO DETAILS: AW Tech ; POWER INPUT :65W @240 VOLTS ; NO OF INPUTS : 4 ; METHOD : AIR COOLED ; TYPE : LED
Item1    Material, PLASTIC ; MODEL: 55' Inches ; MAKE : SONY ; SUPPLIER/PO DETAILS: DK MART ; POWER INPUT :55W @240 VOLTS ; NO OF INPUTS : 5 ; METHOD : NEO AIR COOLED ; TYPE : SMART LED
Item1    Material, Teflon ; MODEL: 42' Inches ; MAKE : LG ; SUPPLIER/PO DETAILS: AW Tech ; POWER INPUT :65W @240 VOLTS ; NO OF INPUTS : 4 ; METHOD : AIR COOLED ; TYPE : LED
Item1     MATERIAL, PLASTIC ; MAKE  : VIDEOCON ; POWER INPUT        : 22V /240 VOLT ; COMPLETED UNIT ; SPARES
Item1    MATERIAL ; MAKE : SONY ; SUPPLIER/PO DETAILS: AW Tech; ; COMPLETED UNIT ; UNIT PARTS
 

Ожидаемый результат

 Item                MODEL       Make    Supplier/PO Details  Power Input    No Of Inputs  Method      Type      Completed Units

Material, Teflon    28' Inches  SAMSUNG       AW Tech        65W @240 VOLTS     4        Air Cooled    LED        
Material, PLASTIC   55' Inches  SONY          DK Material    55W @240 VOLTS     5      NEO AIR COOLED Smart LED    
Material, Teflon    42' Inches  LG            AW Tech        65W @240 VOLTS     4        Air Cooled    LED  
MATERIAL, PLASTIC               VIDEOCON                     22V /240 VOLTS                                         SPARES
Material                        SONY          AW Tech                                                               UNIT PARTS
 

Код, который я пытался :

 df = pd.read_csv("C:UsersInputTest.csv")

for row in df.Column2:
  cols = row.split(';')
 

Как я могу создать другой столбец, используя значения Column2, и присвоить соответствующие значения соответствующим именам столбцов?

Комментарии:

1. Мы можем закодировать это, но похоже, что вы пытаетесь декодировать json, за исключением того, что вы выбросили кавычки ( 'MAKE' : 'SAMSUNG' ), что усложняет задачу. Не могли бы вы, пожалуйста, восстановить ввод с оставленными кавычками?

2. @smci — Ввод такой же, как и в вопросе. Я хочу просмотреть столбец 2, создать столбец с ключами и присвоить ему значения. После создания столбца необходимо присвоить значения остальным строкам. Как указано в Ожидаемом выходе.

3. @Джеймс — Есть ли что-то неправильное в опечатках , когда вы редактируете вопрос

4. Да, я исправил ваш вопрос, и по какой-то причине вы решили его откатить. Можете ли вы объяснить, почему? Было ли что-то не так в моей правке?

Ответ №1:

Сначала разделите точки с запятой между 8 полями с необязательными конечными пробелами.

 df['Column2'].str.split(r';[ ]*')
 

Это даст вам список из 8 строковых элементов:

 ['Material, Teflon ', "MODEL: 28' Inches ", 'MAKE : SAMSUNG ', 'SUPPLIER/PO DETAILS: AW Tech ', 'POWER INPUT :65W @240 VOLTS ', 'NO OF INPUTS : 4 ', 'METHOD : AIR COOLED ', 'TYPE : LED']
['Material, PLASTIC ', "MODEL: 55' Inches ", 'MAKE : SONY ', 'SUPPLIER/PO DETAILS: DK MART ', 'POWER INPUT :55W @240 VOLTS ', 'NO OF INPUTS : 5 ', 'METHOD : NEO AIR COOLED ', 'TYPE : SMART LED']
['Material, Teflon ', "MODEL: 42' Inches ", 'MAKE : LG ', 'SUPPLIER/PO DETAILS: AW Tech ', 'POWER INPUT :65W @240 VOLTS ', 'NO OF INPUTS : 4 ', 'METHOD : AIR COOLED ', 'TYPE : LED']
['MATERIAL, PLASTIC ', 'MAKE  : VIDEOCON ', 'POWER INPUT        : 22V /240 VOLT ', 'COMPLETED UNIT ', 'SPARES']
['MATERIAL ', 'MAKE : SONY ', 'SUPPLIER/PO DETAILS: AW Tech', '', 'COMPLETED UNIT ', 'UNIT PARTS']
 

Во-вторых, каждое из этих полей имеет необязательное имя поля и завершающее двоеточие, например » MAKE:». Вы можете просто щелкнуть по необязательному двоеточию и взять элемент [-1], т. е. Выбросить любое имя поля:

 def strip_optional_fields(f):
    result_list = []
    for ff in f:
        if ff.find(':') >= 0:
            result_list.append(ff.rsplit(':')[-1])
        else:
            result_list.append(ff)  # empty-string
    return pd.Series(result_list)
 

Вы можете просмотреть этот вывод с помощью:

 df['Column2'].str.split(r';[ ]*').apply(strip_optional_fields)
 

…или объедините их в новые столбцы справа с помощью:

 pd.concat([df, df['Column2'].str.split(r';[ ]*').apply(strip_optional_fields)], axis=1)
 

затем переименуйте их, изменив df.columns

Комментарии:

1. Спасибо за ответ. Как я могу разделить значения из ключей на : и присвоить значения столбцам с помощью ключей.

2. Выдает ошибку «Ошибка типа: объект ‘float’ не повторяется» в строке «для ff в f:» , Пожалуйста, предложите, как это можно решить

3. @Manz: для меня это прекрасно работает, я много раз это тестировал. В моем коде нигде нет поплавков. Таким образом, ваша ошибка «объект’float’ не может быть повторен» в строке for ff in f: означает, что вы, должно быть, объявили какую-то случайную переменную с плавающей точкой, которая называется f . Повторите код в чистой оболочке, и все будет в порядке.

Ответ №2:

Попробуй:

Идея состоит в том, чтобы преобразовать данные внутри «Столбца 2» в словарь

 from ast import literal_eval


out=df['Column2'].str.title().str.split(' ; ',1,expand=True)
newout=('{"' out[1].replace({':':'":"',' ; ':'","'},regex=True) '"}')
newout=newout.str.rsplit(',',1,expand=True)
m=~(newout[1].str.contains(':').fillna(True))
newout.loc[m,0]=newout.loc[m,0] ':' newout.loc[m,1]
newout.loc[~m,0]=newout.loc[~m,0] ',' newout.loc[~m,1]
newout=pd.DataFrame(newout[0].dropna().astype(str).map(literal_eval).tolist())
newout.insert(0,'Item',out[0])
newout.columns=newout.columns.str.strip()
 

Теперь, если вы напечатаете, newout вы получите нужный кадр данных

Комментарии:

1. Спасибо за ответ, но во время выполнения я получаю ошибку TypeError: неверный тип операнда для унарного ~: ‘float’ в строке «m=~newout[1].str.содержит(‘:’)» , Похоже , это связано со значением NaN, пожалуйста, предложите, как ее решить.

2. @Manz обновил ответ…теперь попробуйте… Если это не сработает, дайте мне знать 🙂

3. Спасибо за помощь. Но при использовании m=~(newout[1].str.содержит(‘:’).fillna(Ложь)) появляется ошибка «Ошибка значения: неправильный узел или строка: nan» в строке «newout=pd.Фрейм данных(newout[0].карта(literal_eval). tolist())». используя dropna (), затем получает ошибку «Синтаксическая ошибка: неожиданный результат при анализе» в той же строке «newout=pd.Фрейм данных(newout[0].карта(literal_eval). толист())»

4. Спасибо, Анураг, Все еще получаю ошибку «Синтаксическая ошибка: неожиданный результат при анализе» При выполнении строки «newout=pd.DataFrame(newout[0].dropna().map(literal_eval). tolist())» , Любое предположение, в котором я ошибаюсь.

5. @Manz какова была полная обратная связь?… потому что он работал для данного образца фрейма данных

Ответ №3:

Вы можете использовать разделение и использовать expand=True , если хотите создать дополнительные столбцы для разделенных значений,

 df_expanded = df['Column2'].str.split(r';[ ]*', expand=True)
 

Затем вы можете индивидуально обработать эти столбцы, чтобы удалить любой префикс / суффикс, который вы хотите удалить.