Гибкая цепочка в Python pandas

#python #pandas #chaining

#python #pandas #цепочка

Вопрос:

Настройка

Я последовательно применяю два метода к объекту pandas styler, например

 df.style 
  .applymap(mapping1, subset=["column_a"]) 
  .applymap(mapping2, subset=["column_b"])
  

Однако сопоставления, которые я применяю, различаются. Например, я могу понять, что хотел бы добавить новое сопоставление с именем mapping3 для столбца column_c . Ради расширяемости я хотел бы иметь возможность быстро добавлять сопоставление и применять его, не добавляя строку к приведенному выше фрагменту.

Мой вопрос

Я хочу гибко предоставлять сопоставления и применять их все к df , где входные данные представляют собой список сопоставлений (например mappings = [(mapping1, col1), (mapping2, col2), (mapping3, col3)] , а выходные данные представляют собой стилизованный фрейм данных.

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

Воспроизводимый пример

 import pandas as pd

df = pd.DataFrame({
    "column_a": [-1, -2, 3, 4],
    "column_b": ["good", "bad", "neutral", "amazing"],
    "column_c": [0.1, 0.9, 0.5, 1]
})


def mapping1(val):
    if val < 0:
        color = "red"
    elif val > 0:
        color = "green"
    else:
        color = "black"
    return "background-color: %s" % color


def mapping2(val):
    if val == "amazing":
        color = "purple"
    else:
        color = "black"
    return "color: %s" % color


def mapping3(val):
    if val < 0.8:
        color = "orange"
    if val >= 0.8:
        color = "green"
    return "color: %s" % color


styler = df.style 
    .applymap(mapping1, subset=['column_a']) 
    .applymap(mapping2, subset=["column_b"]) 
    .applymap(mapping3, subset=["column_c"])

styler
  

Ответ №1:

Вот способ, использующий style.apply и отменяющий dict

 mappings = [(mapping1, 'column_a'), (mapping2, 'column_b'), (mapping3, 'column_c')]

df.style.apply({v:k for k,v in mappings})
  

введите описание изображения здесь

Ответ №2:

Мы можем выполнять applymap внутри цикла:

 mappings = [
    (mapping1, 'column_a'),
    (mapping2, 'column_b'),
    (mapping3, 'column_c')]

x = df.style
for m in mappings:
    x = x.applymap(m[0], m[1])

x