Удалить повторную информацию в столбцах из панд - PullRequest
0 голосов
/ 07 декабря 2018

Мне нужно очистить информационный фрейм панды, удалить повторяющуюся информацию.Например:

    name                                       strength
770 Vitamin B12 Tab 500mcg                     500 mcg
771 Vitamin B12 Tab 5mcg                       5 mcg
772 Vitamin B12 Tablets 250mcg                 250 mcg
773 Vitamin B12-folic Acid                     None
774 Vitamin B6 & B12 With Folic Acid           None
775 Vitamin Deficiency Injectable System - B12 None
776 Vitamine 110 Liq                           None
777 Vitamine B-12 Tab 100mcg                   100 mcg
778 Vitamine B12 25 Mcg - Tablet               25 mcg
779 Vitamine B12 250mcg                        250 mcg

Из первого столбца name мне нужно удалить информацию в strength, а именно:

    name                                       strength
770 Vitamin B12 Tab                            500 mcg
771 Vitamin B12 Tab                            5 mcg
772 Vitamin B12 Tablets                        250 mcg
773 Vitamin B12-folic Acid                     None
774 Vitamin B6 & B12 With Folic Acid           None
775 Vitamin Deficiency Injectable System - B12 None
776 Vitamine 110 Liq                           None
777 Vitamine B-12 Tab                          100 mcg
778 Vitamine B12 - Tablet                      25 mcg
779 Vitamine B12                               250 mcg

Обратите внимание, представление силы в name может не совсем соответствовать тому, что в столбце strength до пробела (500 мкг против 500 мкг)

Моим простым решением было зациклить все возможные комбинации strength и, если есть совпадение вname столбец, замените его пустым символом:

new_df = []

for i in df:
    for j in df.strength.dropna().drop_duplicates().tolist():
        for k in i.split():
            if j == k: 
                new_df.append((i, i.replace(j, '')))

print(new_df)

Он работает, однако у меня много данных, и это самый непитонный и неэффективный способ реализации.

Есть предложения?

Ответы [ 4 ]

0 голосов
/ 07 декабря 2018

Использование пакета re для удаления ненужной избыточной строки и функции apply для строк в пандах DataFrame должно выполнить эту работу.

В приведенном ниже коде вы видите возможное решение:

import pandas as pd
import re

def removeReduntantData(row):
    if row["strength"] is not None:
        string = row["strength"].replace(" ", "\s?")
        return re.sub(re.compile(string+"\s?", re.IGNORECASE), "", row["name"]).strip()
    else:
        return row["name"]

df = pd.DataFrame({"name":["Vitamin B12 Tab 500mcg","Vitamin B12 Tab 5mcg","Vitamin B12 Tablets 250mcg","Vitamin B12-folic Acid","Vitamin B6 & B12 With Folic Acid","Vitamin Deficiency Injectable System - B12","Vitamine 110 Liq","Vitamine B-12 Tab 100mcg","Vitamine B12 25 Mcg - Tablet","Vitamine B12 250mcg"],\
"strength":["500 mcg","5 mcg","250 mcg",None,None,None,None,"100 mcg","25 mcg","250 mcg"]})

df["name"] = df.apply(removeReduntantData, axis=1)

Выходные данные DataFrame равны:

>>> df
                                         name strength
0                             Vitamin B12 Tab  500 mcg
1                             Vitamin B12 Tab    5 mcg
2                         Vitamin B12 Tablets  250 mcg
3                      Vitamin B12-folic Acid     None
4            Vitamin B6 & B12 With Folic Acid     None
5  Vitamin Deficiency Injectable System - B12     None
6                            Vitamine 110 Liq     None
7                           Vitamine B-12 Tab  100 mcg
8                       Vitamine B12 - Tablet   25 mcg
9                                Vitamine B12  250 mcg

Таким образом, вы в конечном итоге используете столбец strength для поиска избыточной строки в столбце name и удаления их,принимая во внимание, что лишняя строка может не иметь пробела между ними.

0 голосов
/ 07 декабря 2018
new_df=[]  
df= df[df[strength]!=None]# Firstly select the column with Non None values.     
df['name']= df[name].str.split()   
for i in df[name]:  
   for j in df[strength]:    
        if j in i:   
            i.remove(j)   
        else:   
             pass   
   new_df.append(' '.join(i))

Это может быть лучше.Во-первых, мы сокращаем ваши данные и один из циклов for, который сделает сложность кода o (n2) вместо o (n3)

0 голосов
/ 07 декабря 2018

Допущение (я): образец силы всегда "цифра + пробел (необязательно) + мкг".Там были бы способы обобщить это больше, если это необходимо.

Вы можете использовать regex и df.apply.

Сначала вы должны определить шаблон, который вы ищете, используя re.compile().Затем вы используете re.sub() в столбце name, как показано в коде ниже.

import re
import pandas as pd

# Creates a DataFrame for testing
df = pd.DataFrame({"name":["Vitamin B12 500 MCG tab", "Vitamin Deficiency Injectable System - B12", 
"Vitamin Deficiency Injectable System - B12 25 mcg"],"strenght":["500 mcg", "None", "25 mcg"]})

# creates the pattern we are looking for
p = re.compile(r'[\d]+\s?mcg', re.IGNORECASE) 

# Replace our column name with the value we want
df["name"] = df["name"].apply(lambda x: re.sub(p,'',x))
print(df)

Более подробную информацию о df.apply можно найти здесь и используя регулярное выражение с Python здесь

0 голосов
/ 07 декабря 2018

Я бы не совпал со всеми возможными комбинациями силы.Поскольку элементы, кажется, содержат примерно одинаковые символы для обоих столбцов, вероятно, было бы достаточно использовать столбец силы для нечеткого поиска в столбце имени.

Вы можете искать без учета регистра с пробелами и без пробелов, и вы могли бывероятно, большинство задач выполнено.

Поиск без учета регистра можно выполнить с помощью регулярных выражений в python:

import re

# case insensitive without whitespace
if re.search('5 mcg'.replace(" ",""), 'Vitamin B12 Tab 5mcg', re.IGNORECASE):
    # is True
elif re.search('25 mcg', 'Vitamine B12 25 Mcg - Tablet', re.IGNORECASE):
    # is True

Конечно, замените литералы там вашими переменными.

РЕДАКТИРОВАТЬ: Там может быть более эффективный способ сделать это с помощью регулярных выражений, поэтому, если кто-то более опытный с ними, я был бы рад узнать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...