Фильтрация фрейма данных по условию pandas (разбиение строки) - PullRequest
1 голос
/ 10 января 2020

У меня есть фрейм данных, как показано ниже

Prop_ID    Unit_ID      Prop_Usage      Unit_Usage
1          1            Res             Res
1          2            Res             Com
1          3            Res             Ind
1          4            Res             Res
2          1            Com             Res
2          2            Com             Com
2          3            Com             Com
3          1            Ind             Ind
3          2            Ind             Com
4          1            Res - Com       Res
4          2            Res - Com       Com
4          3            Res - Com       Ind
5          1            Com - Res       Res
5          2            Com - Res       Com
5          3            Com - Res       Ind
5          4            Com - Res       Com

Из приведенного выше ясно, что одно свойство может иметь более 1 единицы. Это означает, что единицы измерения являются подкатегорией свойств.

Из приведенных выше данных я хочу отфильтровать строки, в которых Prop_Usage не совпадает с Unit_Usage. У нас в столбце Prop_Usage есть категория: Res - Com, затем Unit_Usage, тогда использование единицы может быть либо Res, либо Com.

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

Prop_ID    Unit_ID      Prop_Usage      Unit_Usage
1          2            Res             Com
1          3            Res             Ind
2          1            Com             Res
3          2            Ind             Com
4          3            Res - Com       Ind
5          3            Com - Res       Ind

Ответы [ 2 ]

1 голос
/ 10 января 2020

Если ваш фрейм данных достаточно мал, чтобы производительность не беспокоила:

mask = df[['Prop_Usage', 'Unit_Usage']] \
        .assign(
            Prop_Usage=lambda x: x['Prop_Usage'].str.split(' - ').apply(set),
            Selected=lambda x: ~x.apply(lambda row: row['Unit_Usage'] in row['Prop_Usage'], axis=1)
        )

df.loc[mask['Selected']]

Что он делает:

  • Скопируйте Prop_Usage и Unit_Usage в новый dataframe
  • Заменить столбец Prop_Usage на разделенную версию самого себя. Каждая строка в версии «после» представляет собой набор единиц измерения

Например:

Prop_Usage             Prop_Usage
(before)               (after)
----------             ----------
Res                    {Res}
Res - Com        -->   {Res, Com}
Com - Res - Com        {Com, Res}
  • Проверка, находится ли Unit_Usage в наборе, построчно , Если это не так, отметьте Selected = True
  • Фильтруйте исходный кадр данных, где Selected Истина

Обратите внимание, что, поскольку он использует .apply(..., axis=1), производительность не будет большой для больших фреймов данных.

0 голосов
/ 10 января 2020

Pandas может напрямую сравнивать столбцы строка за строкой с:

df[~df.apply(lambda x: x.Unit_Usage in x.Prop_Usage, axis=1)]

Применение лямбда-функции будет сравнивать строки в каждой строке и видеть, есть ли то, что в Unit_usage, в Prop_Usage для этой строки и производить логическая серия. Вы можете использовать эту логическую серию для нарезки кадра данных.

...