Выделите python pandas фрейм данных, если найдены определенные значения - PullRequest
0 голосов
/ 06 мая 2020

Это из последнего примера в главе 7 «Pandas Cookbook» с использованием набора данных flight.csv. Цель состоит в том, чтобы найти самую длинную серию задержек для каждой комбинации авиакомпании и аэропорта отправления. Я немного изменил свои собственные.

def max_delay_streak(df):
  df = df.reset_index(drop=True)
  s = 1- df['ON_TIME']
  s1 = s.cumsum()
  streak = s.mul(s1).diff().where(lambda x: x < 0).ffill().add(s1, fill_value =0)
  df['streak'] = streak
  last_idx = streak.idxmax()
  max_streak = streak.max()

  # my slight modification here to accommodate delay streak equals 0
  if max_streak == 0:
      first_idx = 0
  else:
     first_idx = last_idx - max_streak + 1

  df_return = df.loc[[first_idx, last_idx],['MONTH','DAY']]
  df_return['streak'] = max_streak  
  df_return.index = ['first','last']
  df_return.index.name = 'streak_row'

  # search and operate zero streak

  # my adjustment to find index where there is no delay streak
  # df_return[df_return['streak'] == 0].index
  # gets the MultiIndex([('EV', 'PHX', 'first'), ('EV', 'PHX',  'last')],
  #      names=['AIRLINE', 'ORG_AIR', 'streak_row'])
  no_streak = df_return[df_return['streak'] == 0].index
  # get the data from respective index and return month/day into '-'
  df_return.loc[no_streak,['MONTH','DAY']] = '-'
  return df_return 

  flights.sort_values(['MONTH','DAY','SCHED_DEP']).groupby(['AIRLINE','ORG_AIR']).apply(max_delay_streak)

Здесь код работает нормально. Затем я пытаюсь выделить строки желтым цветом, где полоса задержки равна 0 (или любому другому числу).

желаемый_результат

Я пробовал 2 метода, которые программа запускает без ошибка и создайте исходный фрейм данных, ничего не выделяя.

Метод 1: повторно используйте .lo c logi c в последней строке указанной выше программы, чтобы использовать индекс для перехода к определенным c ряд для добавления цвета.

df_return.loc[no_streak].style.apply('background-color: yellow',axis=1)

Метод 2: уродливый способ. Я попытался извлечь все индексы (авиакомпания, аэропорт происхождения, первый / последний), сравнить их с индексом полосы нулевой задержки, где информация хранится в переменной no_streak (в данном случае (EV, PHX, первый '), (' EV ',' PHX ',' последний ')). Если условие выполнено, примените цвет.

df_return.style.apply(['background-color: yellow' for x in list(df_return.index) if x in list(no_streak)], axis=1)

Почему мой код не смог получить желаемое изображение? Возможно ли достичь цели?

Ответы [ 2 ]

0 голосов
/ 10 мая 2020

Хотя код не изящный, но я наконец получил то, что хотел. Введите число, и фрейм данных выделит все соответствующие строки, которые соответствуют критериям поиска, результат будет таким: pi c. введите здесь описание изображения

df = flights.sort_values(['MONTH','DAY','SCHED_DEP']).groupby(['AIRLINE','ORG_AIR']).apply(max_delay_streak)
streak_no = input("Enter streak no: ")
streak_no = int(streak_no)
color_dict = {"AA": "lightcoral", "AS": "orangered", "B6": "orange", "DL": "yellow" , "EV": "lawngreen", "F9": "palegreen", "HA": "lightcyan", "MQ": "aqua",
  "NK": "skyblue", "OO": "lightsteelblue", "UA": 'lavender', "US": "violet", "VX": "magenta", "WN": "pink"}

# first level coloring
# get the first level index value
first_level_index = df.index.get_level_values(0)
# get unique first level value where criteria is met
no_streak_row_unique = df[df['streak'] == streak_no].index.get_level_values(0).unique()
# decide which row in first level to color
first_level_color_arrangement = [ {'selector': f'.row{i}.level0', 
          'props': [('background-color', color_dict[j])]} if j in no_streak_row_unique else {'selector': f'.row{i}.level0', 
          'props': [('background-color', 'default')]}for i,j in enumerate(first_level_index)]

# second level unique
second_level_index = list(zip(df.index.get_level_values(0) , df.index.get_level_values(1)))
# no_streak_row_2_unique
no_streak_row_2_unique = list(set(zip(df[df['streak'] == streak_no].index.get_level_values(0), df[df['streak'] == streak_no].index.get_level_values(1))))
second_level_color_arrangement = [ {'selector': f'.row{i}', 
          'props': [('background-color', color_dict[j[0]])]} if j in no_streak_row_2_unique else {'selector': f'.row{i}', 
          'props': [('background-color', 'default')]}for i,j in enumerate(second_level_index)]

df.style.set_table_styles(first_level_color_arrangement + second_level_color_arrangement)
0 голосов
/ 07 мая 2020

Выполните стилизацию вне функции max_delay_streak ().

import pandas as pd
flights = pd.read_csv('flights.csv')
flights['ON_TIME'] = flights['ARR_DELAY'].lt(15).astype(int)
flights_agg = flights.sort_values(['MONTH', 'DAY', 'SCHED_DEP']).groupby(['AIRLINE', 'ORG_AIR']).apply(max_delay_streak)
flights_agg.style.apply(lambda x: ['background-color: yellow']*3 if x.streak == 0 else ['background-color: default']*3, axis=1)

, где max_delay_streak () - это функция, определенная в вопросе.

...