{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Päivitetty 2024-02-07 / Aki Taanila\n" ] } ], "source": [ "from datetime import datetime\n", "print(f'Päivitetty {datetime.now().date()} / Aki Taanila')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# DataFrame\n", "\n", "Tästä muistiosta voit aloittaa vaikka et olisi koskaan koodannut Pythonilla.\n", "\n", "Paketti (kutsutaan myös kirjastoksi) on kokoelma valmista ohjelmakoodia, jota voin käyttää omissa ohjelmissani. Data-analytiikan peruspaketti on nimeltään **pandas**. \n", "\n", "Useimmat data-analytiikassa tarvittavat paketit sisältyvät Anacondaan ja Colabiin. Jos käytät Minicondaa, niin sinun pitää asentaa jokainen käytettävä paketti erikseen.\n", "\n", "Jos paketti on valmiiksi asennettu, niin voin tuoda sen käyttööni **import**-komennolla. Esimerkiksi `import pandas as pd` tuo pandas-paketin käyttööni siten että voin seuraavissa koodisoluissa viitata siihen lyhenteellä **pd**.\n", "\n", "Muistion solun voit suorittaa näppäinyhdistelmillä **ctrl-enter** (pysyt samassa solussa) tai **shift-enter** (siirryt seuraavaan soluun).\n", "\n", "Pandas-kirjaston keskeinen olio on **DataFrame** (muistuttaa taulukkolaskennan taulukkoa). Seuraavassa tutustun dataframe-olioon yksinkertaisen esimerkkidatan avulla." ] }, { "cell_type": "code", "execution_count": 2, "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", "
TuoteVarastoHinta
0muikkukukko815
1lanttukukko1012
2lihalörtsy53
3kasvislörtsy73
\n", "
" ], "text/plain": [ " Tuote Varasto Hinta\n", "0 muikkukukko 8 15\n", "1 lanttukukko 10 12\n", "2 lihalörtsy 5 3\n", "3 kasvislörtsy 7 3" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Tuon data-analytiikan peruskirjaston\n", "import pandas as pd\n", "\n", "# Tallennan datan sanakirjaan (dictionary)\n", "# Sanakirjan ympärillä on aina aaltosulkeet {}\n", "# Listan ympärillä on aina hakasulkeet []\n", "data = {'Tuote': ['muikkukukko', 'lanttukukko', 'lihalörtsy', 'kasvislörtsy'],\n", " 'Varasto': [8, 10, 5, 7],\n", " 'Hinta': [15, 12, 3, 3]}\n", "\n", "# Luon sanakirjasta dataframen, jonka nimeksi annan df\n", "df = pd.DataFrame(data)\n", "\n", "# Näytän dataframen\n", "df" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(4, 3)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Dataframen rivien ja sarkkeiden määrä\n", "df.shape" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "RangeIndex(start=0, stop=4, step=1)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Rivi-indeksi (dataframen vasemmanpuoleisin sarake)\n", "# Jos rivi-indeksiä ei ole erikseen määritelty, niin se sisältää juoksevat numerot 0, 1, 2,...\n", "df.index" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['Tuote', 'Varasto', 'Hinta'], dtype='object')" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Sarakeindeksi (dataframen sarakeotsikot)\n", "df.columns" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Indeksihaku iloc\n", "\n", "Voin viitata dataframen yksittäisiin soluihin indeksinumeroilla. Huomaa, että indeksinumerot alkavat numerosta 0!" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Lanttukukon hinta indeksihaulla (1=lanttukukon rivi, 2=hinta-sarake)\n", "df.iloc[1, 2]" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tuote lihalörtsy\n", "Varasto 5\n", "Hinta 3\n", "Name: 2, dtype: object" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Tiedot lihalörtsyn riviltä (rivi 2)\n", "df.iloc[2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Haku indeksin tunnuksella loc\n", "\n", "Voin viitata tietokehikon yksittäisiin soluihin indeksien tunnuksilla." ] }, { "cell_type": "code", "execution_count": 8, "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", "
VarastoHinta
Tuote
muikkukukko815
lanttukukko1012
lihalörtsy53
kasvislörtsy73
\n", "
" ], "text/plain": [ " Varasto Hinta\n", "Tuote \n", "muikkukukko 8 15\n", "lanttukukko 10 12\n", "lihalörtsy 5 3\n", "kasvislörtsy 7 3" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Siirrän tuote-sarakkeen arvot rivi-indeksin arvoiksi\n", "df = df.set_index('Tuote')\n", "df" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Varasto 5\n", "Hinta 3\n", "Name: lihalörtsy, dtype: int64" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Lihalörtsyn tiedot\n", "df.loc['lihalörtsy']" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Lihalörtsyn hinta\n", "df.loc['lihalörtsy','Hinta']" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tuote\n", "muikkukukko 15\n", "lanttukukko 12\n", "Name: Hinta, dtype: int64" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Hintatiedot muikkukukosta lanttukukkoon\n", "df.loc['muikkukukko':'lanttukukko', 'Hinta']" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Tuote\n", "muikkukukko 15\n", "lanttukukko 12\n", "lihalörtsy 3\n", "kasvislörtsy 3\n", "Name: Hinta, dtype: int64" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Tuotteiden hinnat\n", "# Kaksoispiste tarkoittaa, että otetaan mukaan kaikki rivit\n", "df.loc[:, 'Hinta']" ] }, { "cell_type": "code", "execution_count": 13, "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", "
Hinta
Tuote
muikkukukko15
lanttukukko12
lihalörtsy3
kasvislörtsy3
\n", "
" ], "text/plain": [ " Hinta\n", "Tuote \n", "muikkukukko 15\n", "lanttukukko 12\n", "lihalörtsy 3\n", "kasvislörtsy 3" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Jos tuloksena on indeksin lisäksi vain yhden sarakkeen tietoja, niin tulos ei ole dataframe, vaan series\n", "# Voin kuitenkin muuttaa tuloksen dataframeksi to_frame-funktiolla\n", "df.loc[:, 'Hinta'].to_frame()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Hieman laskentaa\n", "\n", "Voin laskea dataframeen uusia sarakkeita olemassaolevien sarakkeiden pohjalta." ] }, { "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
VarastoHintaArvo
Tuote
muikkukukko815120
lanttukukko1012120
lihalörtsy5315
kasvislörtsy7321
\n", "
" ], "text/plain": [ " Varasto Hinta Arvo\n", "Tuote \n", "muikkukukko 8 15 120\n", "lanttukukko 10 12 120\n", "lihalörtsy 5 3 15\n", "kasvislörtsy 7 3 21" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Lasken tuotteiden varastoarvot Arvo-sarkkeeseen\n", "df['Arvo'] = df['Varasto']*df['Hinta'] \n", "df" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "276" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Lasken summan Arvo-sarakkeesta\n", "df['Arvo'].sum()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "240" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Kukkojen varastoarvo\n", "df.loc['muikkukukko':'lanttukukko', 'Arvo'].sum()" ] }, { "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
VarastoHintaArvo%
Tuote
muikkukukko81512043.478261
lanttukukko101212043.478261
lihalörtsy53155.434783
kasvislörtsy73217.608696
\n", "
" ], "text/plain": [ " Varasto Hinta Arvo %\n", "Tuote \n", "muikkukukko 8 15 120 43.478261\n", "lanttukukko 10 12 120 43.478261\n", "lihalörtsy 5 3 15 5.434783\n", "kasvislörtsy 7 3 21 7.608696" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Lisään %-sarakkeen (tuotteen osuus varaston kokonaisarvosta)\n", "df['%'] = df['Arvo']/df['Arvo'].sum()*100\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Voin muotoilla dataframea muotoilukoodilla **{:.0f}**:\n", "* Muotoilukoodi kirjotetaan aaltosulkujen väliin\n", "* **:** on aloitusmerkki\n", "* **.0** tarkoittaa 0 desimaalia\n", "* **f** tarkoittaa liukulukua (float)" ] }, { "cell_type": "code", "execution_count": 18, "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", "
 VarastoHintaArvo%
Tuote    
muikkukukko81512043
lanttukukko101212043
lihalörtsy53155
kasvislörtsy73218
Yhteensä3033276100
\n" ], "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Lisään dataframeen summarivin\n", "df.loc['Yhteensä'] = df.sum()\n", "\n", "# Esitän dataframen ilman desimaaleja käyttämällä muotoilukoodia\n", "df.style.format('{:.0f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Rivien ja sarakkeiden vaihtaminen (transponointi)" ] }, { "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", " \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", "
TuotemuikkukukkolanttukukkolihalörtsykasvislörtsyYhteensä
Varasto8105730
Hinta15123333
Arvo1201201521276
%434358100
\n" ], "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# T (transpose) vaihtaa dataframen rivit ja sarakkeet\n", "df.T.style.format('{:.0f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Luettelo muistikirjassa käytetyistä funktioista ja toiminnoista\n", "\n", "* Paketin tuonti **import**-toiminnolla; esimerkkinä **pandas**-paketin tuonti\n", "* Merkkijono (**string**) kirjoitetaan heittomerkkien '' väliin (myös lainausmerkit \"\" käyvät). Merkkijonoja ovat esimerkiksi tiedostonimet, dataframen sarakeotsikot (muuttujien nimet), muuttujien tekstimuotoiset arvot. Huomaa kuitenkin, että Pythonin muuttujien nimiä ei kirjoitetan heittomerkkien väliin (esimerkiksi df, n jne.) \n", "* Pythonin tietorakenne **lista**, joka kirjoitetaan hakasulkujen sisään\n", "* Pythonin tietorakenne **sanakirja** (**dictionary**), joka kirjoitetaan aaltosulkujen sisään\n", "* Pandas-kirjaston tietorakenteet **dataframe** ja **series**\n", "* **pd.DataFrame()** dataframen luominen\n", "* **df.shape** datan rivien ja sarakkeiden lukumäärät\n", "* **df.index** dataframen vasemman reunan indeksi\n", "* **df.columns** dataframen yläreunan indeksi\n", "* **df.iloc[]** viittaus dataframen viipaleeseen indeksinumeroilla\n", "* **df.set_index()** sarakkeen siirtäminen vasemman reunan indeksiin\n", "* **df.loc[]** viittaus dataframen viipaleeseen indeksitunnuksilla\n", "* **df.to_frame()** series-tyyppisen datan muuttaminen dataframeksi\n", "* **df.sum()** summafunktio\n", "* **df.style.format()** dataframen muotoilu\n", "* **df.T** dataframen rivit sarakkeiksi ja päinvastoin\n", "\n", "Lisäksi opittiin laskemaan dataframeen uusia sarakkeita ja käyttämään muotoilukoodeja **style.format**-funktion yhteydessä." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lisätietoa\n", "\n", "Tutustu DataFrame-olion ohjesivuun: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html\n", " \n", "Data-analytiikka Pythonilla https://tilastoapu.wordpress.com/python/" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.5" } }, "nbformat": 4, "nbformat_minor": 4 }