将一个 Pandas 数据框转换为类别和项目列表?

huangapple go评论66阅读模式
英文:

How do you transform a Pandas data frame into category and list of items?

问题

我正在尝试将任务列表输出为PDF。输出应为:

  • 廊道
    • 任务
    • 任务
    • 任务
  • 前厅
    • 任务
    • 任务
    • 任务
  • [房间名]
    • 任务
    • ...

我有以下代表需要在给定周内在每个房间中发生的清洁任务的Pandas数据框。

               Room                                           Task Weeks
0       廊道                                吸尘地板  ABCD
2       廊道                                   拖地板  ABCD
4    前厅                                吸尘地板  ABCD
5    前厅                           清空吸尘器  ABCD
6    前厅  用微湿布擦拭踢脚板  A
7    前厅                                   拖地板  ABCD
8    前厅   如果桌布脏了换桌布  ABCD
10  客厅                                吸尘地板  ABCD
11  客厅  用微湿布擦拭踢脚板  A
12  客厅                                   整理沙发  ABCD

我尝试了groupby

today_tasks = (
    task_data[task_data["Weeks"].str.contains(schedule_week)]
    .groupby("Room", group_keys=True)
    .apply(lambda x: x)
)
print(today_tasks.head(10))

它返回以下结果:

                                             Room                    Task Weeks
Room                                                                           
浴室                      62                浴室            吸尘地板  ABCD
                        63                浴室               拖地板  ABCD
                        64                浴室              清洁浴缸  ABCD
                        65                浴室      清洁淋浴喷头    AC
                        66                浴室      清洁淋浴玻璃    AC
                        68                浴室            清洁马桶  ABCD
                        69                浴室              清洁水槽    AC
楼上前卧室  45  楼上前卧室            吸尘地板  ABCD
                        46  楼上前卧室               拖地板  ABCD
                        47  楼上前卧室  从床上取下床单  ABCD

我明白我可以通过循环将数据框放入字典中,但这并不感觉很符合Pandas的风格。然而,这个集合只有70行,而且每周只需要执行一次,所以性能可能并不那么重要。尽管如此,我还是更喜欢遵守最佳实践。是否有更好的方法?

英文:

I am trying to output a task list as PDF. The output should be

  • Hallway
    • Task
    • Task
    • Task
  • Front Room
    • Task
    • Task
    • Task
  • [Room name]
    • Task
    • ...

I have the following Pandas data frame which represents the cleaning tasks that need to occur in each room on a given week.

           Room                                           Task Weeks
0       Hallway                                   Vacuum floor  ABCD
2       Hallway                                      Mop floor  ABCD
4    Front Room                                   Vacuum floor  ABCD
5    Front Room                           Empty Vacuum Cleaner  ABCD
6    Front Room  Wipe skirting boards with slightly damp cloth     A
7    Front Room                                      Mop floor  ABCD
8    Front Room      If tablecloth is dirty, change tablecloth  ABCD
10  Living Room                                   Vacuum floor  ABCD
11  Living Room  Wipe skirting boards with slightly damp cloth     A
12  Living Room                                      Tidy sofa  ABCD

I have tried groupby

today_tasks = (
    task_data[task_data["Weeks"].str.contains(schedule_week)]
    .groupby("Room", group_keys=True)
    .apply(lambda x: x)
)
print(today_tasks.head(10))

Which returns the following

                                         Room                    Task Weeks
Room                                                                           
Bathroom               62                Bathroom            Vacuum floor  ABCD
                       63                Bathroom               Mop floor  ABCD
                       64                Bathroom              Clean bath  ABCD
                       65                Bathroom      Clean shower heads    AC
                       66                Bathroom      Clean shower glass    AC
                       68                Bathroom            Clean toilet  ABCD
                       69                Bathroom              Clean sink    AC
Front Bedroom Upstairs 45  Front Bedroom Upstairs            Vacuum floor  ABCD
                       46  Front Bedroom Upstairs               Mop floor  ABCD
                       47  Front Bedroom Upstairs  Remove sheets from bed  ABCD

I appreciate that I could for through and put the data frame into a dictionary, but this does not feel very Pandas-native. Equally, however, the set is only 70 rows long and only needs to be executed weekly, so performance probably does not matter too much. Nonetheless, I do prefer to abide by best practices.

Is there a better way to do it?

答案1

得分: 1

你可以使用 `jinja2` 渲染 HTML 模板然后通过外部工具如 `wkhtmltopdf``pdfkit` 库将其转换为 PDF

```python
import jinja2
import io

templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)

def render_pdf(filename, **kwargs):
    template = templateEnv.get_template('template.html')
    output = template.render(**kwargs)
    return output

for week, subdf in df.groupby('Weeks'):
    room_tasks = subdf.groupby('Room')['Task'].agg(list).to_dict()
    print(render_html(week=week, room_tasks=room_tasks))

输出:

<!-- 周 A -->
<html>
<title>周 A</title>
<body>
<ul>
  <li>前厅</li>
  <ul>
    <li>用微湿布擦踢脚板</li>
  </ul> 
</ul>
<ul>
  <li>客厅</li>
  <ul>
    <li>用微湿布擦踢脚板</li>
  </ul> 
</ul>
</body>
</html>

<!-- 周 ABCD -->
<html>
<title>周 ABCD</title>
<body>
<ul>
  <li>前厅</li>
  <ul>
    <li>吸尘地板</li>
  </ul><ul>
    <li>清空吸尘器</li>
  </ul><ul>
    <li>拖地</li>
  </ul><ul>
    <li>如果桌布脏了,换桌布</li>
  </ul> 
</ul>
<ul>
  <li>走廊</li>
  <ul>
    <li>吸尘地板</li>
  </ul><ul>
    <li>拖地</li>
  </ul> 
</ul>
<ul>
  <li>客厅</li>
  <ul>
    <li>吸尘地板</li>
  </ul><ul>
    <li>整理沙发</li>
  </ul> 
</ul>
</body>
</html>

template.html

<html>
<title>周 {{ week }}</title>
<body>
{%- for room, tasks in room_tasks.items() %}
<ul>
  <li>{{ room }}</li>
  {% for task in tasks -%}
  <ul>
    <li>{{ task }}</li>
  </ul>
  {%- endfor %} 
</ul>
{%- endfor %}
</body>
</html>
英文:

You can render HTML template with jinja2 then convert to PDF with external tool like wkhtmltopdf via pdfkit library:

import jinja2
import io

templateLoader = jinja2.FileSystemLoader(searchpath=&quot;./&quot;)
templateEnv = jinja2.Environment(loader=templateLoader)

def render_pdf(filename, **kwargs):
    template = templateEnv.get_template(&#39;template.html&#39;)
    output = template.render(**kwargs)
    return output

for week, subdf in df.groupby(&#39;Weeks&#39;):
    room_tasks = subdf.groupby(&#39;Room&#39;)[&#39;Task&#39;].agg(list).to_dict()
    print(render_html(week=week, room_tasks=room_tasks))

Output:

&lt;!-- Week A --&gt;
&lt;html&gt;
&lt;title&gt;Week A&lt;/title&gt;
&lt;body&gt;
&lt;ul&gt;
  &lt;li&gt;Front Room&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Wipe skirting boards with slightly damp cloth&lt;/li&gt;
  &lt;/ul&gt; 
&lt;/ul&gt;
&lt;ul&gt;
  &lt;li&gt;Living Room&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Wipe skirting boards with slightly damp cloth&lt;/li&gt;
  &lt;/ul&gt; 
&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;

&lt;!-- Week ABCD --&gt;
&lt;html&gt;
&lt;title&gt;Week ABCD&lt;/title&gt;
&lt;body&gt;
&lt;ul&gt;
  &lt;li&gt;Front Room&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Vacuum floor&lt;/li&gt;
  &lt;/ul&gt;&lt;ul&gt;
    &lt;li&gt;Empty Vacuum Cleaner&lt;/li&gt;
  &lt;/ul&gt;&lt;ul&gt;
    &lt;li&gt;Mop floor&lt;/li&gt;
  &lt;/ul&gt;&lt;ul&gt;
    &lt;li&gt;If tablecloth is dirty, change tablecloth&lt;/li&gt;
  &lt;/ul&gt; 
&lt;/ul&gt;
&lt;ul&gt;
  &lt;li&gt;Hallway&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Vacuum floor&lt;/li&gt;
  &lt;/ul&gt;&lt;ul&gt;
    &lt;li&gt;Mop floor&lt;/li&gt;
  &lt;/ul&gt; 
&lt;/ul&gt;
&lt;ul&gt;
  &lt;li&gt;Living Room&lt;/li&gt;
  &lt;ul&gt;
    &lt;li&gt;Vacuum floor&lt;/li&gt;
  &lt;/ul&gt;&lt;ul&gt;
    &lt;li&gt;Tidy sofa&lt;/li&gt;
  &lt;/ul&gt; 
&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;

template.html

&lt;html&gt;
&lt;title&gt;Week {{ week }}&lt;/title&gt;
&lt;body&gt;
{%- for room, tasks in room_tasks.items() %}
&lt;ul&gt;
  &lt;li&gt;{{ room }}&lt;/li&gt;
  {% for task in tasks -%}
  &lt;ul&gt;
    &lt;li&gt;{{ task }}&lt;/li&gt;
  &lt;/ul&gt;
  {%- endfor %} 
&lt;/ul&gt;
{%- endfor %}
&lt;/body&gt;
&lt;/html&gt;

huangapple
  • 本文由 发表于 2023年3月31日 02:15:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75891653.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定