Выделите значение столбца на основе другого значения столбца в пандах - PullRequest
0 голосов
/ 06 июня 2018

У меня есть такая функция:

def highlight_otls(df):
    return ['background-color: yellow']

И вот такой DataFrame:

price   outlier 
1.99       F,C
1.49       L,C
1.99         F
1.39         N

Я хочу выделить определенный столбец в моей df на основеэто условие другого столбца:

data['outlier'].str.split(',').str.len() >= 2

Поэтому, если значения столбца df ['outlier']> = 2, я хочу выделить соответствующий столбец df ['price'].(Таким образом, первые 2 цены должны быть выделены в моем кадре данных выше).

Я попытался сделать это, выполнив следующее, что выдает ошибку:

data['price'].apply(lambda x: highlight_otls(x) if (x['outlier'].str.split(',').str.len()) >= 2, axis=1)

Любая идея о том, каксделать это правильно?

Ответы [ 3 ]

0 голосов
/ 13 июня 2018

Используйте Styler.apply.(Для вывода в формат xlsx используйте функцию to_excel.)

Предположим, набор данных

other   price   outlier
0   X   1.99    F,C
1   X   1.49    L,C
2   X   1.99    F
3   X   1.39    N

def hightlight_price(row):
    ret = ["" for _ in row.index]
    if len(row.outlier.split(",")) >= 2:
        ret[row.index.get_loc("price")] = "background-color: yellow"
    return ret

df.style.\
    apply(hightlight_price, axis=1).\
    to_excel('styled.xlsx', engine='openpyxl')

Из документации , "DataFrame.style атрибут - это свойство, которое возвращает объект Styler."

Мы передаем нашу функцию стиля hightlight_price в Styler.apply и требуем строковый характер функции с axis=1,(Напомним, что мы хотим закрасить ячейку price в каждой строке на основе информации outlier в той же строке .)

Наша функция hightlight_price сгенерирует визуальный стиль для каждого ряда .Для каждой строки row сначала создается стиль для столбцов other, price и outlier, равный ["", "", ""].Мы можем получить правильный индекс, чтобы изменить только часть price в списке с row.index.get_loc("price"), как в

ret[row.index.get_loc("price")] = "background-color: yellow"
# ret becomes ["", "background-color: yellow", ""]

Результаты

enter image description here

0 голосов
/ 13 июня 2018

Я предлагаю использовать пользовательскую функцию для возврата styled DataFrame по условию, последнее экспорт в файл Excel :

def highlight_otls(x):
    c1 = 'background-color: yellow'
    c2 = '' 

    mask = x['outlier'].str.split(',').str.len() >= 2
    df1 =  pd.DataFrame(c2, index=df.index, columns=df.columns)
    #modify values of df1 column by boolean mask
    df1.loc[mask, 'price'] = c1

    #check styled DataFrame
    print (df1)

                          price outlier
    0  background-color: yellow        
    1  background-color: yellow        
    2                                  
    3                               
    return df1

df.style.apply(highlight_otls, axis=None).to_excel('styled.xlsx', engine='openpyxl')

pic

0 голосов
/ 06 июня 2018

Ключевые точки

  1. Вам необходимо получить доступ к значениям в нескольких столбцах для функции lambda, поэтому примените ее ко всему фрейму данных, а не только к столбцу цен.
  2. Вышеприведенное также решает проблему, которая применяется к серии, не имеет аргумента axis.
  3. Добавьте else x, чтобы исправить синтаксическую ошибку в условной логике для вашей lambda
  4. Когда вы индексируете x в lambda, это значение, а не серия, поэтому убейте вызовы атрибута str и просто вызовите len для него.

Поэтому попробуйте:

data.apply(lambda x: highlight_otls(x) if len(x['outlier'].split(',')) >= 2 else x, axis=1)

Вывод

0    [background-color: yellow]
1    [background-color: yellow]
2                  [None, None]
3                  [None, None]
dtype: object

Один из способов справиться с нулевыми значениями выбросов согласно вашему комментарию - это рефакторинг условной логики выделения в highlight_otls функция:

def highlight_otls(x):                                                            
     if len(x['outlier'].split(',')) >= 2:
         return ['background-color: yellow']
     else:
         return x

data.apply(lambda x: highlight_otls(x) if pd.notnull(x['outlier']) else x, axis=1)

Кстати, вы можете захотеть вернуть что-то вроде ['background-color: white'] вместо x, если вы не хотите применять подсветку.

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