* **All methods operate on columns by default. Pass `'axis=1'` to process the rows instead.**
* **Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a single column: `'<DF>.loc[row_k, (col_k_1, col_k_2)]'`.**
* **Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a column: `'<DF>.loc[row_key, (col_key_1, col_key_2)]'`.**
#### DataFrame — Multi-Index:
```python
@ -3348,7 +3348,7 @@ c 6 7
<DF> = <DF>.xs(row_keys, level=<ints>) # Rows that have first key on first level, etc.
<DF> = <DF>.set_index(col_keys) # Combines multiple columns into a multi-index.
<S/DF> = <DF>.stack/unstack(level=-1) # Combines col keys with row keys or vice versa.
@ -817,15 +817,15 @@ player = Player(point, direction) <span class="hljs-comment">#
</code></pre></div>
<ul>
<li><strong>Return value of str() should be readable and of repr() unambiguous.</strong></li>
<li><strong>If only repr() is defined, it will also be used for str().</strong></li>
<li><strong>Methods decorated with <codeclass="python hljs"><spanclass="hljs-string">'@staticmethod'</span></code> do not receive 'self' nor 'cls' as their first arg.</strong></li>
<li><strong>Return value of str() should be readable and of repr() unambiguous.</strong></li>
<li><strong>If only repr() is defined, it will also be used for str().</strong></li>
<li><strong>Methods decorated with <codeclass="python hljs"><spanclass="hljs-string">'@staticmethod'</span></code> do not receive 'self' nor 'cls' as their first argument.</strong></li>
</ul>
<div><h4id="expressionsthatcallthestrmethod">Expressions that call the str() method:</h4><pre><codeclass="python language-python hljs">print(<obj>)
<div><h2id="json"><ahref="#json"name="json">#</a>JSON</h2><p><strong>Text file format for storing collections of strings and numbers.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">import</span> json
<str> = json.dumps(<object>) <spanclass="hljs-comment"># Converts object to JSON string.</span>
<object> = json.loads(<str>) <spanclass="hljs-comment"># Converts JSON string to object.</span>
<str>= json.dumps(<list/dict>)<spanclass="hljs-comment"># Converts collection to JSON string.</span>
<coll> = json.loads(<str>)<spanclass="hljs-comment"># Converts JSON string to collection.</span>
</code></pre></div>
<div><h3id="readobjectfromjsonfile">Read Object from JSON File</h3><pre><codeclass="python language-python hljs"><spanclass="hljs-function"><spanclass="hljs-keyword">def</span><spanclass="hljs-title">read_json_file</span><spanclass="hljs-params">(filename)</span>:</span>
<div><h3id="readcollectionfromjsonfile">Read Collection from JSON File</h3><pre><codeclass="python language-python hljs"><spanclass="hljs-function"><spanclass="hljs-keyword">def</span><spanclass="hljs-title">read_json_file</span><spanclass="hljs-params">(filename)</span>:</span>
<div><h2id="pickle"><ahref="#pickle"name="pickle">#</a>Pickle</h2><p><strong>Binary file format for storing Python objects.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">import</span> pickle
<div><h2id="sqlite"><ahref="#sqlite"name="sqlite">#</a>SQLite</h2><p><strong>A server-less database engine that stores each database into a separate file.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">import</span> sqlite3
<conn> = sqlite3.connect(<path>) <spanclass="hljs-comment"># Opens existing or new file. Also ':memory:'.</span>
<div><h2id="sqlite"><ahref="#sqlite"name="sqlite">#</a>SQLite</h2><p><strong>A server-less database engine that stores each database into its own file.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">import</span> sqlite3
<conn> = sqlite3.connect(<path>) <spanclass="hljs-comment"># Opens existing or new file. Also ':memory:'.</span>
<div><h3id="read-1">Read</h3><pre><codeclass="python language-python hljs"><cursor> = <conn>.execute(<spanclass="hljs-string">'<query>'</span>) <spanclass="hljs-comment"># Can raise a subclass of sqlite3.Error.</span>
<tuple> = <cursor>.fetchone() <spanclass="hljs-comment"># Returns next row. Also next(<cursor>).</span>
<list> = <cursor>.fetchall() <spanclass="hljs-comment"># Returns remaining rows. Also list(<cursor>).</span>
<div><h3id="read-1">Read</h3><pre><codeclass="python language-python hljs"><cursor> = <conn>.execute(<spanclass="hljs-string">'<query>'</span>) <spanclass="hljs-comment"># Can raise a subclass of sqlite3.Error.</span>
<tuple> = <cursor>.fetchone() <spanclass="hljs-comment"># Returns next row. Also next(<cursor>).</span>
<list> = <cursor>.fetchall() <spanclass="hljs-comment"># Returns remaining rows. Also list(<cursor>).</span>
</code></pre></div>
<div><h3id="write-1">Write</h3><pre><codeclass="python language-python hljs"><conn>.execute(<spanclass="hljs-string">'<query>'</span>) <spanclass="hljs-comment"># Can raise a subclass of sqlite3.Error.</span>
<conn>.commit() <spanclass="hljs-comment"># Saves all changes since the last commit.</span>
<conn>.rollback() <spanclass="hljs-comment"># Discards all changes since the last commit.</span>
<div><h3id="write-1">Write</h3><pre><codeclass="python language-python hljs"><conn>.execute(<spanclass="hljs-string">'<query>'</span>) <spanclass="hljs-comment"># Can raise a subclass of sqlite3.Error.</span>
<conn>.commit() <spanclass="hljs-comment"># Saves all changes since the last commit.</span>
<conn>.rollback() <spanclass="hljs-comment"># Discards all changes since the last commit.</span>
</code></pre></div>
<div><h4id="or">Or:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">with</span><conn>: <spanclass="hljs-comment"># Exits the block with commit() or rollback(),</span>
<conn>.execute(<spanclass="hljs-string">'<query>'</span>) <spanclass="hljs-comment"># depending on whether any exception occurred.</span>
<div><h4id="or">Or:</h4><pre><codeclass="python language-python hljs"><spanclass="hljs-keyword">with</span><conn>: <spanclass="hljs-comment"># Exits the block with commit() or rollback(),</span>
<conn>.execute(<spanclass="hljs-string">'<query>'</span>) <spanclass="hljs-comment"># depending on whether any exception occurred.</span>
</code></pre></div>
<div><h3id="placeholders">Placeholders</h3><pre><codeclass="python language-python hljs"><conn>.execute(<spanclass="hljs-string">'<query>'</span>, <list/tuple>) <spanclass="hljs-comment"># Replaces '?'s in query with values.</span>
<conn>.execute(<spanclass="hljs-string">'<query>'</span>, <dict/namedtuple>) <spanclass="hljs-comment"># Replaces ':<key>'s with values.</span>
<li><strong>Passed values can be of type str, int, float, bytes, None or bool (stored as 1 or 0).</strong></li>
<li><strong>Passed values can be of type str, int, float, bytes, None, or bool (stored as 1 or 0).</strong></li>
</ul>
<div><h3id="example-1">Example</h3><p><strong>Values are not actually saved in this example because <codeclass="python hljs"><spanclass="hljs-string">'conn.commit()'</span></code> is omitted!</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-meta">>>></span>conn = sqlite3.connect(<spanclass="hljs-string">'test.db'</span>)
<spanclass="hljs-meta">>>></span>conn.execute(<spanclass="hljs-string">'CREATE TABLE person (person_id INTEGER PRIMARY KEY, name, height)'</span>)
<div><h3id="sqlalchemy">SQLAlchemy</h3><p><strong>Library for interacting with various DB systems via SQL, method chaining, or ORM.</strong></p><pre><codeclass="python language-python hljs"><spanclass="hljs-comment"># $ pip3 install sqlalchemy</span>
<spanclass="hljs-keyword">from</span> sqlalchemy <spanclass="hljs-keyword">import</span> create_engine, text
@ -2720,13 +2720,13 @@ c <span class="hljs-number">6</span> <span class="hljs-number">7</span>
<ul>
<li><strong>All methods operate on columns by default. Pass <codeclass="python hljs"><spanclass="hljs-string">'axis=1'</span></code> to process the rows instead.</strong></li>
<li><strong>Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a single column: <codeclass="python hljs"><spanclass="hljs-string">'<DF>.loc[row_k, (col_k_1, col_k_2)]'</span></code>.</strong></li>
<li><strong>Fifth result's columns are indexed with a multi-index. This means we need a tuple of column keys to specify a column: <codeclass="python hljs"><spanclass="hljs-string">'<DF>.loc[row_key, (col_key_1, col_key_2)]'</span></code>.</strong></li>
</ul>
<div><h4id="dataframemultiindex">DataFrame — Multi-Index:</h4><pre><codeclass="python language-python hljs"><DF> = <DF>.xs(row_key, level=<int>) <spanclass="hljs-comment"># Rows with key on passed level of multi-index.</span>
<DF> = <DF>.xs(row_keys, level=<ints>) <spanclass="hljs-comment"># Rows that have first key on first level, etc.</span>
<DF> = <DF>.set_index(col_keys) <spanclass="hljs-comment"># Combines multiple columns into a multi-index.</span>
<S/DF> = <DF>.stack/unstack(level=<spanclass="hljs-number">-1</span>) <spanclass="hljs-comment"># Combines col keys with row keys or vice versa.</span>