Ускорьте Pandas: найдите все столбцы, которые соответствуют набору условий

У меня есть данные, представленные с помощью pandas DataFrame, которые, например, выглядят следующим образом:

| id | entity | name | value | location

где id — это значение integer, entity — это integer , name — это string, value — это integer, а location — это string (например, США, Калифорния, Великобритания и т. д.).

Теперь я хочу добавить в этот фрейм данных новый столбец, столбец «flag», где значения присваиваются следующим образом:

for d in df.iterrows():

    if d.entity == 10 and d.value != 1000 and d.location == CA:
        d.flag = "A" 
    elif d.entity != 10 and d.entity != 0 and d.value == 1000 and d.location == US:
        d.flag = "C"
    elif d.entity == 0 and d.value == 1000 and d.location == US"
        d.flag = "B"
    else:
        print("Different case")

Есть ли способ ускорить это и использовать некоторые встроенные функции вместо цикла for?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
138
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

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

conditions = [
    (d.entity == 10) & (d.value != 1000) & (d.location == 'CA'),
    (d.entity != 10) & (d.entity != 0) & (d.value == 1000) & (d.location == 'US'),
    (d.entity == 0) & (d.value == 1000) & (d.location == 'US')
]

choices = ["A", "C", "B"]

df['flag'] = np.select(conditions, choices, default = "Different case")

Спасибо, это выглядит интересно! Один вопрос - должен ли я делать это для каждой строки (поскольку d - это одна строка), так что все еще в цикле?

Ziva 10.04.2019 15:46

Нет, это векторизованное решение. Циклы в общем питоне и пандах медленные. Поэтому используйте последнюю строку, чтобы создать новый столбец с именем flag. @Зива

Erfan 10.04.2019 15:47

Добавьте () с побитовым and -> & для работы с numpy.select:

m = [
    (d.entity == 10) & (d.value != 1000) & (d.location == 'CA'),
    (d.entity != 10) & (d.entity != 0) & (d.value == 1000) & (d.location == 'US'),
    (d.entity == 0) & (d.value == 1000) & (d.location == 'US')
]

df['flag'] = np.select(m, ["A", "C", "B"], default = "Different case")

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

Если это действительно так, вы можете использовать df.apply, предоставив ему функцию, которая вычисляет значение для конкретной строки:

def flag_value(row):
    if row.entity == 10 and row.value != 1000 and row.location == CA:
        return "A"
    elif row.entity != 10 and row.entity != 0 and row.value == 1000 and row.location == US:
        return "C"
    elif row.entity == 0 and row.value == 1000 and row.location == US:
        return "B"
    else:
        return "Different case"

df['flag'] = df.apply(flag_value, axis=1)

Взгляните на этот связанный вопрос для получения дополнительной информации.

Если вы действительно хотите найти все столбцы, которые задают некоторое условие, обычный способ сделать это с фреймом данных Pandas — использовать df.loc и индексацию:

only_a_cases = df.loc[df.entity == 10 & df.value != 1000 & df.location == "CA"]
# or:
only_a_cases = df.loc[lambda df: df.entity == 10 & df.value != 1000 & df.location == "CA"]

Другие вопросы по теме