Разбор данных из столбца с использованием if - PullRequest
1 голос
/ 15 октября 2019

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

Пример:

     df['COL1']
0 PB~Cucumber_IT~_TL~Vegatables_SP~
1 PB~Potato_IT~_TB~Starch_SP~
2 PB~Onion_IT~_PE~Vegatables_BA~

Я пробовал:

for i in df['COL1']:
    if 'TL~' in df['COL1'][i]:
        df['COL2'][i] = df['COL1'][i].str.split('TL~').str[1].str.split('_SP~').str[0]
     elif 'TB~' in df['COL1'][i]:
         df['COL2'][i] = df['COL1'][i].str.split('TB~').str[1].str.split('_SP~').str[0]
     elif 'PE~' in df['COL1'][i]:
         df['COL2'][i] = df['COL1'][i].str.split('PE~').str[1].str.split('_BA~').str[0]

Ожидаемый вывод:

     df['COL2']
0 Vegatables
1 Starch
2 Vegatables

df.info () вывод: * note - для соответствияЯ удалил некоторые столбцы и для конфиденциальности переименовал их. thiscolumn столбец в df, который я пытаюсь использовать:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 54 entries, 0 to 53
Data columns (total 16 columns):
notthiscolumn4            54 non-null object
thiscolumn                54 non-null object
notthiscolumn3            54 non-null object
notthiscolumn2            54 non-null object
notthiscolumn             54 non-null object
dtypes: object(16)

Я получил множество ошибок при попытке разных вещей, таких как: - str не имеет атрибута str - я пробовалиспользование iterrows, когда он сказал, что это объект np.object, но затем возникли проблемы с индексами. - длина значений не соответствует длине индекса.

Любое направление ценится!

Ответы [ 2 ]

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

Нет необходимости использовать numpy, у pandas есть несколько различных опций для операций такого типа.

import pandas as pd

def parse_row_col1(row):
    result = ""
    if 'TL~' in row.COL1:
        result = row.COL1.split('TL~')[1].split('_SP~')[0]
    elif 'TB~' in row.COL1:
        result = row.COL1.split('TB~')[1].split('_SP~')[0]
    elif 'PE~' in row.COL1:
        result = row.COL1.split('PE~')[1].split('_BA~')[0]
    return result


parse_res = pd.Series((parse_row_col1(curr) for curr in df.itertuples(index=False)))

Этот метод, повторяющийся в кортежах строк, не так быстр, как при использовании numpy's select,но должен быть гораздо менее сложным при работе с большим количеством условий. И не только это, но, как указывает @rpanai в своем ответе, select может обрабатывать только взаимоисключающие условия, тогда как решение выше действует независимо.

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

IIUC, это тот случай, когда вы можете подать заявление np.select см. документ

import numpy as np
import pandas as pd
from io import StringIO

txt ="""COL1
0 PB~Cucumber_IT~_TL~Vegatables_SP~
1 PB~Potato_IT~_TB~Starch_SP~
2 PB~Onion_IT~_PE~Vegatables_BA~"""

df = pd.read_csv(StringIO(txt),
                 delim_whitespace=True)

condList = [df["COL1"].str.contains("TL~"),
            df["COL1"].str.contains("TB~"),
            df["COL1"].str.contains("PE~")]

choiceList = [df["COL1"].str.split('TL~').str[1].str[:-4],
              df["COL1"].str.split('TB~').str[1].str[:-4],
              df["COL1"].str.split('PE~').str[1].str[:-4]]

df["COL2"] = np.select(condList, choiceList)

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

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