it-roy-ru.com

pandas: вывод HTML с условным форматированием

Я пытаюсь отформатировать таблицу так, чтобы данные в каждом столбце форматировались в стиле в зависимости от их значений (аналогично условному форматированию в программах для работы с электронными таблицами). Как я могу достичь этого в пандах, используя форматер HTML?

Типичным примером использования является выделение значимых значений в таблице. Например:

    correlation  p-value
0   0.5          0.1
1   0.1          0.8
2   0.9          *0.01*

pandas позволяет определять собственные средства форматирования для вывода HTML - для получения вышеуказанного вывода можно использовать:

import pandas as pd
from pandas.core import format
from StringIO import StringIO
buf = StringIO()
df = pd.DataFrame({'correlation':[0.5, 0.1,0.9], 'p_value':[0.1,0.8,0.01]})
fmt = format.DataFrameFormatter(df, 
          formatters={'p_value':lambda x: "*%f*" % x if x<0.05 else str(x)})
format.HTMLFormatter(fmt).write_result(buf)

Тем не менее, я хотел бы изменить стиль для значимых значений (например, с помощью полужирного шрифта).

Возможным решением было бы присоединить класс CSS к тегам <td> в выводе HTML, который затем можно отформатировать с использованием таблицы стилей CSS. Вышеуказанное станет:

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>correlation</th>
      <th>p_value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td> 0.5</td>
      <td> 0.10</td>
    </tr>
    <tr>
      <td>1</td>
      <td> 0.1</td>
      <td> 0.80</td>
    </tr>
    <tr>
      <td>2</td>
      <td> 0.9</td>
      <td class='significant'> 0.01</td>
    </tr>
  </tbody>
</table>

Правка : В соответствии с предложением @ Andy-Hayden я могу добавить форматирование, просто заменив звездочки на <span class="signifcant">...</span> в моем примере:

import pandas as pd
from StringIO import StringIO
buf = StringIO()
significant = lambda x: '<span class="significant">%f</span>' % x if x<0.05 else str(x)
df = pd.DataFrame({'correlation':[0.5, 0.1,0.9], 'p_value':[0.1,0.8,0.01]})
df.to_html(buf, formatters={'p_value': significant})

Более новые версии панд избегают тегов. Чтобы избежать этого, замените последнюю строку на:

df.to_html(buf, formatters={'p_value': significant}, escape=False)
23
btel

Вы можете использовать метод DataFrame to_html , который поставляется с аргументом formatters.

Более простым решением было бы окружить <span class="significant"> и </span> (вместо *). Примечание: по умолчанию это будет экранировано (т.е. < становится &lt;), поэтому вам нужно будет использовать аргумент escape=False.

20
Andy Hayden

Начиная с pandas 0.17.1, легко применить пользовательское форматирование к HTML-представлению фрейма данных с помощью стиля api .

import pandas as pd

df = pd.DataFrame({
    'correlation':[0.5, 0.1,0.9],
    'p_value':[0.1,0.8,0.01]})
styled_df = df.style.apply(
    lambda x: ['font-weight: bold; background-color: yellow'
               if value <= 0.01 else '' for value in x])
styled_df

 enter image description here

Выходные данные автоматически отображаются в таких интерфейсах, как Блокнот Jupyter Строковое представление HTML можно вернуть с помощью метода render()

print(styled_df.render())
<style  type="text/css" >
    #T_4e49b9da_8451_11e8_9166_605718a99a7frow2_col1 {
            font-weight:  bold;
             background-color:  yellow;
            font-weight:  bold;
             background-color:  yellow;
        }</style>  
<table id="T_4e49b9da_8451_11e8_9166_605718a99a7f" > 
<thead>    <tr> 
        <th class="blank level0" ></th> 
        <th class="col_heading level0 col0" >correlation</th> 
        <th class="col_heading level0 col1" >p_value</th> 
    </tr></thead> 
<tbody>    <tr> 
        <th id="T_4e49b9da_8451_11e8_9166_605718a99a7flevel0_row0" class="row_heading level0 row0" >0</th> 
        <td id="T_4e49b9da_8451_11e8_9166_605718a99a7frow0_col0" class="data row0 col0" >0.5</td> 
        <td id="T_4e49b9da_8451_11e8_9166_605718a99a7frow0_col1" class="data row0 col1" >0.1</td> 
    </tr>    <tr> 
        <th id="T_4e49b9da_8451_11e8_9166_605718a99a7flevel0_row1" class="row_heading level0 row1" >1</th> 
        <td id="T_4e49b9da_8451_11e8_9166_605718a99a7frow1_col0" class="data row1 col0" >0.1</td> 
        <td id="T_4e49b9da_8451_11e8_9166_605718a99a7frow1_col1" class="data row1 col1" >0.8</td> 
    </tr>    <tr> 
        <th id="T_4e49b9da_8451_11e8_9166_605718a99a7flevel0_row2" class="row_heading level0 row2" >2</th> 
        <td id="T_4e49b9da_8451_11e8_9166_605718a99a7frow2_col0" class="data row2 col0" >0.9</td> 
        <td id="T_4e49b9da_8451_11e8_9166_605718a99a7frow2_col1" class="data row2 col1" >0.01</td> 
    </tr></tbody> 
</table>
1
joelostblom