<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ufuncs on 300.Watts</title><link>https://300watts.me/tags/ufuncs/</link><description>Recent content in Ufuncs on 300.Watts</description><generator>Hugo</generator><language>en</language><managingEditor>morristai01@gmail.com (Morris)</managingEditor><webMaster>morristai01@gmail.com (Morris)</webMaster><copyright>This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.</copyright><lastBuildDate>Sat, 26 Aug 2017 11:16:25 +0800</lastBuildDate><atom:link href="https://300watts.me/tags/ufuncs/index.xml" rel="self" type="application/rss+xml"/><item><title>Pandas ufuncs小技巧</title><link>https://300watts.me/posts/pandas-ufuncs%E5%B0%8F%E6%8A%80%E5%B7%A7/</link><pubDate>Sat, 26 Aug 2017 11:16:25 +0800</pubDate><author>morristai01@gmail.com (Morris)</author><guid>https://300watts.me/posts/pandas-ufuncs%E5%B0%8F%E6%8A%80%E5%B7%A7/</guid><description>&lt;blockquote&gt;
 &lt;p&gt;&lt;code&gt;Pandas&lt;/code&gt;的&lt;code&gt;ufuncs&lt;/code&gt;為什麼比&lt;code&gt;apply command&lt;/code&gt;還建議使用?&lt;/p&gt;

&lt;/blockquote&gt;&lt;p&gt;Pandas 有一個&lt;code&gt;apply function&lt;/code&gt;讓你可以針對所有在column的值執行任何functions。注意apply只是比python內建的loop還要快一點點而已！這就是為什麼pandas的內建ufuncs比較推薦使用在columns的預處理(preprocessing)。&lt;br&gt;
&lt;code&gt;ufuncs&lt;/code&gt;是特殊functions(建構在numpy的library)裡面並由&lt;strong&gt;C&lt;/strong&gt;來實行，這就是為何&lt;code&gt;ufuncs&lt;/code&gt;會如此之快。以下會介紹幾種&lt;code&gt;ufuncs&lt;/code&gt;的例子&lt;code&gt;(.diff, .shift, .cumsum, .cumcount, .str commands (作用在字串), .dt commands (作用在日期))&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="範例數據--暑期活動" class="headerLink"&gt;
 &lt;a href="#%e7%af%84%e4%be%8b%e6%95%b8%e6%93%9a--%e6%9a%91%e6%9c%9f%e6%b4%bb%e5%8b%95" class="header-mark"&gt;&lt;/a&gt;範例數據 — 暑期活動&lt;/h2&gt;&lt;p&gt;這裡透過下面的數據集來演示pandas的ufuncs(同一個人可以在不同的時間軸上進行不同的活動)
&lt;img class="tw-inline" loading="lazy" src='https://300watts.me/images/pandas_ufuncs_1.jpeg' alt="pandas_ufuncs_dataset" &gt;&lt;/p&gt;
&lt;p&gt;這裏假設我們的任務是要基於上面的數據集去預測&lt;strong&gt;誰是最有趣的同學&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="1-string-commands" class="headerLink"&gt;
 &lt;a href="#1-string-commands" class="header-mark"&gt;&lt;/a&gt;1. String commands&lt;/h2&gt;&lt;p&gt;&lt;img class="tw-inline" loading="lazy" src='https://300watts.me/images/pandas_ufuncs_2.jpeg' alt="pandas_ufuncs_dataset" &gt;
如果我們想要對字串做切割的話，string commands (which are Ufuncs)是最推薦的：
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img class="tw-inline" loading="lazy" src='https://300watts.me/images/pandas_ufuncs_3.jpeg' alt="pandas_ufuncs_dataset" &gt;
除此之外你可以用&lt;a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.replace.html" target="_blank" rel="noopener noreferrer"&gt;pandas.Series.str.replace&lt;/a&gt;來更有效的清理字串。&lt;/p&gt;
&lt;h2 id="2-group-by-and-value_counts" class="headerLink"&gt;
 &lt;a href="#2-group-by-and-value_counts" class="header-mark"&gt;&lt;/a&gt;2. Group by and value_counts&lt;/h2&gt;&lt;p&gt;透過&lt;code&gt;groupby&lt;/code&gt;和&lt;code&gt;value_counts&lt;/code&gt;我們可以輕鬆數出每個人做過多少次活動：
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;activity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value_counts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img class="tw-inline" loading="lazy" src='https://300watts.me/images/pandas_ufuncs_4.jpeg' alt="pandas_ufuncs_dataset" &gt;
這稱為&lt;a href="https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html" target="_blank" rel="noopener noreferrer"&gt;multi index&lt;/a&gt;，它可以讓我們同時在dataframe中擁有不同的index層，在圖片中人名就是level 0而activity是level 1。&lt;/p&gt;
&lt;h2 id="3-unstack" class="headerLink"&gt;
 &lt;a href="#3-unstack" class="header-mark"&gt;&lt;/a&gt;3. Unstack&lt;/h2&gt;&lt;p&gt;我們也可以創建每個人的活動計數特徵，透過&lt;code&gt;unstack&lt;/code&gt;方法，可以將行與列互換，&lt;code&gt;unstack&lt;/code&gt;會把最低level的index轉換成cloumns，每個人的活動計數會變成cloumns，對於沒有從事該活動的人欄位會維持缺失值&lt;code&gt;NaN&lt;/code&gt;，可以對其進行缺失值填補。
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;activity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value_counts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unstack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img class="tw-inline" loading="lazy" src='https://300watts.me/images/pandas_ufuncs_5.jpeg' alt="pandas_ufuncs_dataset" &gt;&lt;/p&gt;
&lt;h2 id="4-groupby-diff-shift-and-loc--a-great-tip-for-efficiency" class="headerLink"&gt;
 &lt;a href="#4-groupby-diff-shift-and-loc--a-great-tip-for-efficiency" class="header-mark"&gt;&lt;/a&gt;4. groupby, diff, shift, and loc + A great tip for efficiency&lt;/h2&gt;&lt;p&gt;如果能了解一個人在活動中從事的時間，必定能對我們了解誰是最有趣的人有幫助。誰在party待最久？誰在海邊待最久？
對於時間長短最有效的推算方式就是先使用&lt;code&gt;groupby&lt;/code&gt;歸類人名，再用&lt;code&gt;diff()&lt;/code&gt;算出時間差:
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;timestamp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;time_diff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;timestamp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img class="tw-inline" loading="lazy" src='https://300watts.me/images/pandas_ufuncs_6.jpeg' alt="pandas_ufuncs_dataset" &gt;
如果你有大量的數據集，你可以跳過&lt;code&gt;groupby&lt;/code&gt;，只做資料排序，刪除每個人的第一行(不相關的)後直接用&lt;code&gt;diff&lt;/code&gt;。
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;timestamp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;time_diff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;timestamp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;time_diff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
順便一提 ⎯ &lt;code&gt;.shift&lt;/code&gt;可以將每一行向下移動ㄧ格，所以我們就可以用&lt;code&gt;df.name!=df.name.shift()&lt;/code&gt;看看哪一行有改變。
然後&lt;code&gt;.loc&lt;/code&gt;是最推薦用來在特定的indices的columns中set values的選擇！&lt;br&gt;
接著我們把&lt;code&gt;time_diff&lt;/code&gt;單位改成秒：
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;time_diff&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time_diff&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_seconds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
獲取每個row的持續時間：
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;row_duration&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time_diff&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img class="tw-inline" loading="lazy" src='https://300watts.me/images/pandas_ufuncs_7.jpeg' alt="pandas_ufuncs_dataset" &gt;&lt;/p&gt;</description></item></channel></rss>