{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Writing Your First Book\n", "\n", "## An HTML Layout\n", "\n", "```html\n", "\n", " \n", "
\n", " stuff\n", "
\n", "
\n", " more stuff\n", "
\n", " \n", "\n", "```\n", "\n", "\n", "## Excelbird Layout\n", "\n", "```python\n", "Book( # no need to create a variable for it.\n", " Sheet(\n", " Frame( # Columnar dataframe\n", " Col(\n", " Cell(1),\n", " Cell(2),\n", " ),\n", " ),\n", " Stack( # Unstructured horizontal container\n", " Cell(1),\n", " Row(1, 2, 3),\n", " Col(5, 6, 7),\n", " VFrame([[10,20], [30, 40]]),\n", " )\n", " )\n", ").write(path)\n", "```\n", "\n", "---" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Writing your first `Book`" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import excelbird as xb\n", "PATH = \"test.xlsx\"" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "A layout is a nested arrangement of elements. Each element will arrange its children\n", "in a different way. This way, you can re-arrange elements by simply re-arranging your code,\n", "without editing it.\n", "\n", "Every layout is built inside a `Book`. There's no need to assign it to a variable, since there's\n", "nothing you can do to it except call `.write()`.\n", "\n", "`Book` doesn't care what you put inside it. It will just put **each argument into a separate sheet**" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Book 'test.xlsx' saved\n" ] } ], "source": [ "xb.Book(\n", " xb.Cell(1), # sheet1\n", " xb.Cell(2), # sheet2\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "A `Sheet` is a container that arranges its elements **vertically**." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "xb.Book(\n", " xb.Sheet(\n", " xb.Cell(1),\n", " xb.Cell(2),\n", " )\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "A `Col` is also a vertical container, but it's *structured*, and contains **Cells only**" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Cell(1)
Cell(2)
Cell(3)
\n" ], "text/plain": [ "Col([Cell(1), Cell(2), Cell(3)])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xb.Col(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Cell(1)Cell(2)Cell(3)
\n" ], "text/plain": [ "Row([Cell(1), Cell(2), Cell(3)])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xb.Row(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 'import *' should usually be avoided,\n", "# but it will make these demos easier to read\n", "from excelbird import *\n", "\n", "Book(\n", " Sheet(\n", " Col(Cell(1), Cell(2)),\n", " Col(1, 2), # Any value will be converted to Cell\n", " ),\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "That's not quite right. We need a container that's **horizontally arranged** - `Frame`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Book(\n", " Sheet(\n", " Frame(\n", " Col(Cell(1), Cell(2)),\n", " Col(1, 2) # Any value will be converted to Cell\n", " ),\n", " ),\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Auto-open\n", "\n", "Excelbird will **auto-open your workbook** for you if `auto_open=True` is set on the Book. It will even manage your Excel session by **auto-closing the file** first, if it's already open. This feature is highly recommended for development - I **always** use it.\n", "\n", "For this feature to work, the Excel app must already be running. It doesn't matter if any workbooks are open or not, as long as the application is running.\n", "\n", ".. warning::\n", " Issues will likely be encountered when managing workbooks stored in **OneDrive**. In most cases the file will auto-open successfully, but throw an error when trying to auto-close on the next run. To avoid issues, **write your files to Desktop**, or somewhere else outside OneDrive.\n", "\n", "Here's an example to demonstrate syntax. We'll omit this option on future examples just to simplify the code, but you should get in the habit of using it" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Book(\n", " ...,\n", " auto_open=True,\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Sibling Types" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "All containers (besides Book and Sheet) have a **sibling type**: a functionally identical type who arranges its children along the opposite axis.\n", "\n", ".. note::\n", " You may be wondering why siblings must be separate classes, rather than just options specified by keyword argument. The answer is **readability**. Unlike HTML where an element's features are specified in the *opening tag*, Python keyword arguments must go at the bottom, after the children. We enjoy having flow direction declared at the top of an element.\n", "\n", "Col's sibling type is Row, and Frame's sibling type is VFrame. A VFrame contains Rows." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Book(\n", " VFrame(\n", " Row(1, 2, 3),\n", " Row(1, 2, 3),\n", " ),\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Transpose\n", "Call `.transpose()` on any element who has a sibling type to toggle between types" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Book(\n", " VFrame(\n", " Row(1, 2, 3),\n", " Row(1, 2, 3),\n", " ).transpose(), # <-- switch to Frame/Col\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Stacks\n", "\n", "A Stack is an unstructured container that can hold **any child type**, and can **nest other Stacks** inside of itself.\n", "\n", "Stack arranges its children **horizontally**, and has a sibling-type VStack.\n", "\n", ".. note::\n", " If you've been waiting to find out how to place an element *anywhere* on a page, nesting Stacks is one of the tools needed to do so. You'll also need `Gap` to apply spacing, but we'll get to that later.\n", "\n", "Remember how Sheet arranges its elements vertically? This is exactly how a VStack will behave. Here's a quick example of Sheet: We'll place a Frame on top of a Row" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Book(\n", " Sheet(\n", " Frame(\n", " Col(1, 2, 3),\n", " Col(1, 2, 3)\n", " ),\n", " Row(10, 20, 30),\n", " ),\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "To wrap these elements horizontally instead, use a **Stack**." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Book(\n", " Sheet(\n", " Stack(\n", " Frame(\n", " Col(1, 2, 3),\n", " Col(1, 2, 3)\n", " ),\n", " Row(10, 20, 30),\n", " ),\n", " ),\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Nested Stacks\n", "\n", "We can nest Stacks inside of one another. To place a Col right *below* the Row above, we'd nest them in a VStack." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Book(\n", " Sheet(\n", " Stack(\n", " Frame(\n", " Col(1, 2, 3),\n", " Col(1, 2, 3)\n", " ),\n", " VStack(\n", " Row(10, 20, 30),\n", " Col(100, 200, 300),\n", " ),\n", " ),\n", " ),\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Series Headers\n", "\n", "Col and Row have a unique attribute: `header`. The full utility of headers will become apparent later on, but for now, here's how they work:\n", "\n", "- A header is a **string** applied via keyword argument to Col or Row: `Col(1, 2, header=\"My Column\")`\n", "- It will be ignored by cell references created by expressions or functions (more on that later)\n", "- Its styling is independent from the other children, and is set by passing arguments to the `header_style` attribute\n", "- It will be inserted automatically if a pandas Series is given as input data. (Pandas DataFrame holds an array of pandas Series. Each pd.Series has a `name` attribute, which are used as the DataFrame's column names)\n", "- Just like the **id** attribute, headers are unique identifiers that can be referenced globally by expressions (more on that later)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
My Column
Cell(1)
Cell(2)
Cell(3)
\n" ], "text/plain": [ "Col([Cell(1), Cell(2), Cell(3)])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Col(1, 2, 3, header=\"My Column\")" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
My RowCell(1)Cell(2)Cell(3)
\n", "
" ], "text/plain": [ "Row([Cell(1), Cell(2), Cell(3)])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Row(1, 2, 3, header=\"My Row\")" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
First
Cell(1)
Cell(2)
\n" ], "text/plain": [ "Col([Cell(1), Cell(2)])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "df = pd.DataFrame([[1, 3], [2, 4]], columns=['First', 'Second'])\n", "\n", "pandas_series = df['First']\n", "\n", "Col(pandas_series)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "theme = xb.colors.theme\n", "Book(\n", " Col(\n", " 1,\n", " 2,\n", " 3,\n", " header=\"Column\",\n", " fill_color=theme.green1,\n", " header_style=dict(bold=True),\n", " ),\n", " auto_open=True,\n", " zoom=350,\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Frames\n", "\n", "As expected, we can specify header_style at the Frame level to style all our columns" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Book(\n", " Frame(\n", " Col(1, 2, 3, header=\"First\"),\n", " Col(4, 5, 6, header=\"Second\"),\n", " fill_color=theme.green2,\n", " header_style=dict(\n", " fill_color=theme.green1,\n", " bold=True,\n", " auto_shade_font=True, # See styling tutorial\n", " ),\n", " ),\n", ").write(PATH)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Pandas Integration\n", "\n", "When given to Frame/VFrame, pandas Series will be interpreted as the respective child type (Col/Row)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NumberWord
Cell(1)Cell(one)
Cell(2)Cell(two)
Cell(3)Cell(three)
Cell(4)Cell(four)
\n" ], "text/plain": [ "Frame([Col([Cell(1), Cell(2), Cell(3), Cell(4)]), Col([Cell(one), Cell(two), Cell(three), Cell(four)])])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(\n", " zip([1,2,3,4], ['one', 'two', 'three', 'four']),\n", " columns=['Number', 'Word']\n", ")\n", "fr = Frame(\n", " df['Number'],\n", " df['Word'],\n", ")\n", "fr" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "In the same way that we could give a single pandas Series to Col/Row, we can also give a DataFrame to Frame/VFrame" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NumberWord
Cell(1)Cell(one)
Cell(2)Cell(two)
Cell(3)Cell(three)
Cell(4)Cell(four)
\n" ], "text/plain": [ "Frame([Col([Cell(1), Cell(2), Cell(3), Cell(4)]), Col([Cell(one), Cell(two), Cell(three), Cell(four)])])" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr = Frame(df)\n", "fr" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Automatic Iterable Unpacking\n", "\n", "*Why can Frame accept both a 2-dimensional DataFrame or 1-dimensional Series as arguments, and give the same result?*\n", "\n", "Frame/VFrame and Col/Row will look at their child arguments and *attempt* to identify iterables that have higher dimensions than is desired, and effectively *explode* those arguments inplace. Here's a couple examples:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Cell(1)
Cell(2)
Cell(3)
Cell(4)
\n" ], "text/plain": [ "Col([Cell(1), Cell(2), Cell(3), Cell(4)])" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Col(\n", " 1,\n", " [2, 3],\n", " 4\n", ")" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
OneTwoThreeFour
Cell(1)Cell(10)Cell(100)Cell(1000)Cell(100)Cell(10)Cell(1)
Cell(2)Cell(20)Cell(200)Cell(2000)Cell(200)Cell(20)Cell(2)
Cell(3)Cell(30)Cell(300)Cell(3000)Cell(300)Cell(30)Cell(3)
\n" ], "text/plain": [ "Frame([Col([Cell(1), Cell(2), Cell(3)]), Col([Cell(10), Cell(20), Cell(30)]), Col([Cell(100), Cell(200), Cell(300)]), Col([Cell(1000), Cell(2000), Cell(3000)]), Col([Cell(100), Cell(200), Cell(300)]), Col([Cell(10), Cell(20), Cell(30)]), Col([Cell(1), Cell(2), Cell(3)])])" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr = Frame(\n", " # 1-dimensional\n", " pd.Series([1, 2, 3], name=\"One\"),\n", " # 2-dimensional\n", " pd.DataFrame(zip([10,20,30], [100,200,300]), columns=[\"Two\", \"Three\"]),\n", " # 1-dimensional\n", " Col(1000, 2000, 3000, header=\"Four\"),\n", " # 2-dimensional\n", " Frame([100, 200, 300], [10, 20, 30], [1, 2, 3]),\n", ")\n", "fr" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
OneCell(1)Cell(2)Cell(3)
TwoCell(10)Cell(20)Cell(30)
ThreeCell(100)Cell(200)Cell(300)
FourCell(1000)Cell(2000)Cell(3000)
Cell(100)Cell(200)Cell(300)
Cell(10)Cell(20)Cell(30)
Cell(1)Cell(2)Cell(3)
\n", "
" ], "text/plain": [ "VFrame([Row([Cell(1), Cell(2), Cell(3)]), Row([Cell(10), Cell(20), Cell(30)]), Row([Cell(100), Cell(200), Cell(300)]), Row([Cell(1000), Cell(2000), Cell(3000)]), Row([Cell(100), Cell(200), Cell(300)]), Row([Cell(10), Cell(20), Cell(30)]), Row([Cell(1), Cell(2), Cell(3)])])" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr.transpose() # VFrame/Row" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "We gave Frame 4 arguments, but the second and fourth were 2-dimensional, so they were unpacked inplace.\n", "\n", "You should **not** get in the habit of relying on this feature for unconventional use-cases (don't pass a Frame to another Frame). The feature exists to make working with pandas DataFrames and Series easier." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Subscripting/Slicing\n", "\n", ".. note::\n", " **Subscripting** refers to accessing elements in an iterable using square brackets, like `my_list[5]`. **Slicing** refers to selecting multiple elements at a time using *colons*: `my_list[5:8]` will return a new list with elements **5**, **6**, and **7**. Slices can also take a 3rd argument, 'step': `my_list[::2]` means \"select every other element, starting from 0\".\n", "\n", "You can select an element from a Frame/VFrame by its header" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Two
Cell(10)
Cell(20)
Cell(30)
\n" ], "text/plain": [ "Col([Cell(10), Cell(20), Cell(30)])" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr = Frame(\n", " Col(1,2,3, header=\"One\"),\n", " Col(10,20,30, header=\"Two\"),\n", " Col(100,200,300, header=\"Three\"),\n", " Col(1000,2000,3000, header=\"Four\"),\n", " Col(100,200,300, header=\"Five\"),\n", ")\n", "fr['Two']" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Slice by index" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TwoThree
Cell(10)Cell(100)
Cell(20)Cell(200)
Cell(30)Cell(300)
\n" ], "text/plain": [ "Frame([Col([Cell(10), Cell(20), Cell(30)]), Col([Cell(100), Cell(200), Cell(300)])])" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr[1:3]" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "When slicing by header, the **same rules apply**: you will slice **up to** (exclusive of) the second part of the slice" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TwoThree
Cell(10)Cell(100)
Cell(20)Cell(200)
Cell(30)Cell(300)
\n" ], "text/plain": [ "Frame([Col([Cell(10), Cell(20), Cell(30)]), Col([Cell(100), Cell(200), Cell(300)])])" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr['Two':'Four']" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Part 3 of the slice ('step') can be used like normal, but it must be an integer" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
OneThreeFive
Cell(1)Cell(100)Cell(100)
Cell(2)Cell(200)Cell(200)
Cell(3)Cell(300)Cell(300)
\n" ], "text/plain": [ "Frame([Col([Cell(1), Cell(2), Cell(3)]), Col([Cell(100), Cell(200), Cell(300)]), Col([Cell(100), Cell(200), Cell(300)])])" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr[::2]" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
TwoFour
Cell(10)Cell(1000)
Cell(20)Cell(2000)
Cell(30)Cell(3000)
\n" ], "text/plain": [ "Frame([Col([Cell(10), Cell(20), Cell(30)]), Col([Cell(1000), Cell(2000), Cell(3000)])])" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr['Two'::2]" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Filter/Reorder Elements\n", "\n", "Passing a **list** of headers (double brackets), will return a new Frame with the given elements, in the desired order" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ThreeOneTwo
Cell(100)Cell(1)Cell(10)
Cell(200)Cell(2)Cell(20)
Cell(300)Cell(3)Cell(30)
\n" ], "text/plain": [ "Frame([Col([Cell(100), Cell(200), Cell(300)]), Col([Cell(1), Cell(2), Cell(3)]), Col([Cell(10), Cell(20), Cell(30)])])" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr = fr[['Three', 'One', 'Two']]\n", "fr" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
OneTwoThree
Cell(1)Cell(10)Cell(100)
Cell(2)Cell(20)Cell(200)
Cell(3)Cell(30)Cell(300)
\n" ], "text/plain": [ "Frame([Col([Cell(1), Cell(2), Cell(3)]), Col([Cell(10), Cell(20), Cell(30)]), Col([Cell(100), Cell(200), Cell(300)])])" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr = fr[['One', 'Two', 'Three']]\n", "fr" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Assignment\n", "\n", "We can also use subscripting to append new elements to a Frame/VFrame while giving them a header at the same time" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
OneTwoThreeFour
Cell(1)Cell(10)Cell(100)Cell(10)
Cell(2)Cell(20)Cell(200)Cell(20)
Cell(3)Cell(30)Cell(300)Cell(30)
\n" ], "text/plain": [ "Frame([Col([Cell(1), Cell(2), Cell(3)]), Col([Cell(10), Cell(20), Cell(30)]), Col([Cell(100), Cell(200), Cell(300)]), Col([Cell(10), Cell(20), Cell(30)])])" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr['Four'] = Col(10, 20, 30)\n", "fr" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Use the same syntax to modify an existing element" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
OneTwoThreeFour
Cell(1)Cell(10)Cell(100)Cell(10)
Cell(2)Cell(20)Cell(200)Cell(20)
Cell(3)Cell(30)Cell(300)Cell(30)
Cell(4)
Cell(5)
\n" ], "text/plain": [ "Frame([Col([Cell(1), Cell(2), Cell(3), Cell(4), Cell(5)]), Col([Cell(10), Cell(20), Cell(30)]), Col([Cell(100), Cell(200), Cell(300)]), Col([Cell(10), Cell(20), Cell(30)])])" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fr['One'] = Col(1, 2, 3, 4, 5)\n", "fr" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "eda7e54fe21129b67f77862937907ee926f057597a3e2fa1e18ac955e40912b3" } } }, "nbformat": 4, "nbformat_minor": 2 }