Соответствие двум pandas сериям: как найти строковый элемент из одной серии в другой серии, а затем создать новый столбец - PullRequest
1 голос
/ 13 февраля 2020

В настоящее время я работаю над очисткой набора данных о выбросах автомобилей. Вот как выглядит набор данных (только первые 10 строк):

import pandas as pd

cars_em_df = pd.DataFrame({'manufacturer_name_mapped': ['FIAT', 'FIAT','FIAT','FIAT','FIAT'],
'commercial_name':['124 gt multiair auto', '500l wagon pop star t-jet', 
'doblo combi 1.4 95', 'panda  0.9t sge 85 natural power', 'punto 1.4  77 lpg'],
'fuel_type_mapped':['Petrol', 'Petrol', 'Petrol', 'NG-Biomethane', 'LPG'],
'file_year':[2018, 2018, 2018, 2018, 2018], 'emissions': [153,158,165,86,114]})

Меня больше всего интересует столбец 'commercial_name' . Конечная цель заключается в добавлении еще одного столбца к этому фрейму данных, который показывает «очищенную» версию «имя_фрагмента» . У меня есть отдельная серия pandas, которая содержит «правильные» имена, которые следует использовать вместо этих «грязных» имен.

real_model_names = pd.Series(['uno', '147', 'panda', 'punto', '166', '4c', 'brera', 'giulia',
'giulietta', 'gtv'])

Это также все строки. Поэтому в качестве примера я хотел бы посмотреть в каждой строке 'commercial_name' , содержит ли оно какое-либо из имен из 'real_model_names series' . Например, 'punto' из 'real_model_names' можно найти в записи 'punto 1.4 77 lpg' из столбца 'commercial_name', Итак, я хотел бы (в новом столбце в car_em_df) иметь 'punto' рядом с ним. Если его не удается найти, я бы хотел, чтобы отображалось исходное «грязное» имя.

Я попытался определить функцию, которую затем применил бы к столбцу «Commercial_name». Я попробовал это:

def str_ops(series):
   for i in real_model_names:
      if i in series:
         return series.replace(series, i)
      else:
         return series

И в качестве следующего шага я бы применил эту функцию и добавил бы ее к кадру данных в качестве нового столбца:

commercial_name_cleaned = cars_em_df.commercial_name.apply(str_ops)
cars_em_df.insert(3,value=commercial_name_cleaned,column='commercial_name_cleaned') 

Однако это просто не Делать что-нибудь. Новый столбец просто показывает те же записи, что и «Commercial_name».

Кто-нибудь знает, как решить эту проблему? Есть лучший способ сделать это?

Заранее большое спасибо!

1 Ответ

0 голосов
/ 13 февраля 2020

Ваш l oop был на правильном пути. Самый читаемый и прямой способ, которым я могу придумать, сделать это:

def str_ops(x):
    for y in real_model_names: 
        if y in x: 
            return y 
    return x

cars_em_df['commercial_name_cleaned'] = cars_em_df['commercial_name'].apply(str_ops)

# Result
cars_em_df
  manufacturer_name_mapped                   commercial_name fuel_type_mapped  file_year  emissions    commercial_name_cleaned
0                     FIAT              124 gt multiair auto           Petrol       2018        153       124 gt multiair auto
1                     FIAT         500l wagon pop star t-jet           Petrol       2018        158  500l wagon pop star t-jet
2                     FIAT                doblo combi 1.4 95           Petrol       2018        165         doblo combi 1.4 95
3                     FIAT  panda  0.9t sge 85 natural power    NG-Biomethane       2018         86                      panda
4                     FIAT                 punto 1.4  77 lpg              LPG       2018        114                      punto
...