Длина списка Dynami c, применяемая в качестве операторов в кадре данных - PullRequest
1 голос
/ 22 января 2020

Если бы у меня был такой список:

myList = ['a', 'b', 'c']

и df вроде бы так

original df

и я бы хотел чтобы создать новый столбец в df на основе a, b, c, я могу сделать что-то вроде этого:

df['new_col_1'] = df[myList[0]] & df[myList[1]] & df[myList[2]]

Логическое значение присутствует в каждой из ячеек, поэтому результат либо True / False.

Проблема в том, что иногда 'myList' может иметь длину не 3, а 2, 4 и c. Есть ли простой способ компенсировать переменную длину myList?

Кроме того, как только для 'new_col_1' установлено значение True (в данном случае только для 'mnl'), тогда это должно установить все его значения. столбцы (так a, b, c) в FALSE, потому что 'new_col_1' теперь TRUE. Результат должен быть:

enter image description here

Ответы [ 3 ]

4 голосов
/ 22 января 2020

Прежде всего давайте создадим фрейм данных и список из вашего примера:

import pandas as pd

df = pd.DataFrame(
    [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 1],
        [0, 0, 0, 1, 0],
        [0, 0, 0, 0, 0],
        [1, 1, 1, 0, 1],
    ],
    index=["abc", "def", "ghi", "jkl", "mnl"],
    columns=list("abcde")
).applymap(bool)

my_list = ['a', 'b', 'c']

Затем давайте разделим проблему на две части

Часть 1: Создать new_col

В основном вам нужно взять все столбцы из my_list и выполнить операцию and построчно. Вы можете сделать это с помощью all(axis=1):

df["new_col"] = df[my_list].all(axis=1)

Результат будет:

         a      b      c      d      e  new_col
abc  False  False  False  False  False    False
def  False  False  False  False   True    False
ghi  False  False  False   True  False    False
jkl  False  False  False  False  False    False
mnl   True   True   True  False  True     True

Часть 2. Обновление таблицы на основе new_col

Это можно сделать с помощью оператора loc. Мы хотим повлиять на все строки, где new_col равно True и установить False для столбцов в my_list:

df.loc[df["new_col"], my_list] = False

Результат будет:

         a      b      c      d      e  new_col
abc  False  False  False  False  False    False
def  False  False  False  False   True    False
ghi  False  False  False   True  False    False
jkl  False  False  False  False  False    False
mnl  False  False  False  False  True     True
2 голосов
/ 22 января 2020

здесь есть другой способ использования df.dot и np.where (данные любезно предоставлены @villoro)

c = df.dot(df.columns).eq(''.join(my_list)) #assuming all the columns are booleans
final = pd.DataFrame(np.where(c[:,None],False,df),columns=df.columns,index=df.index)
                                                             .assign(new_col1=c)

print(final)  

         a      b      c      d      e  new_col1
abc  False  False  False  False  False     False
def  False  False  False  False   True     False
ghi  False  False  False   True  False     False
jkl  False  False  False  False  False     False
mnl  False  False  False  False  False      True
2 голосов
/ 22 января 2020

Здесь будет достаточно простого for l oop.

Кодовое решение для игры в гольф будет использовать reduce

from functools import reduce
import operator

df['new_col_1'] = reduce(operator.and_, map(df.__getitem__, myList))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...