<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Pandas 計算連續(xù)行為天數(shù)的幾種思路

          共 3873字,需瀏覽 8分鐘

           ·

          2021-06-05 11:36


          大家好,我是才哥。

          最近在處理數(shù)據(jù)的時候遇到一個需求,核心就是求取最大連續(xù)行為天數(shù)。類似需求在去年筆者剛接觸 pandas 的時候也做過《利用Python統(tǒng)計連續(xù)登錄N天或以上用戶》,這里可以用同樣的方法進行實現(xiàn)。

          這里用北京空氣質(zhì)量數(shù)據(jù)作為案例進行演示,需求是找出北京空氣質(zhì)量連續(xù)污染最長持續(xù)多久并確定其周期。

          圖1:案例數(shù)據(jù)

          以上圖中數(shù)據(jù)來算,可以看到從1月21日-1月26日空氣質(zhì)量連續(xù)污染持續(xù)了6天。

          不過,在實際的數(shù)據(jù)處理中,原始數(shù)據(jù)往往會較大,并不一定能直接看出來。接下來,介紹幾種解決方案供大家參考。

          1. 獲取案例數(shù)據(jù)

          大家可以通過以下方式獲取案例數(shù)據(jù)。

          import akshare as ak

          air_quality_hist_df = ak.air_quality_hist(city="北京", period="day", start_date="2021-01-01", end_date="2021-04-26")
          air_quality_hist_df.head()
          圖2:akshare數(shù)據(jù)預(yù)覽

          由于只需要用到aqi,并按照國際標(biāo)準(zhǔn)進行優(yōu)良與污染定級,這里簡單做下數(shù)據(jù)處理如下:

          import pandas as pd

          # 重置索引
          aqi = air_quality_hist_df['aqi'].reset_index()
          # 將aqi列改為int類型
          aqi.aqi = aqi.aqi.astype('int')
          # 使用分箱進行空氣質(zhì)量定級
          aqi['空氣質(zhì)量'] = pd.cut(aqi.aqi,
                                  bins=[0,100,500],
                                  labels=['優(yōu)良','污染'])
          # 取10個樣本預(yù)覽
          aqi.sample(10)
          圖3:處理后數(shù)據(jù)

          2. 求連續(xù)污染持續(xù)天數(shù)

          結(jié)合上次的《利用Python統(tǒng)計連續(xù)登錄N天或以上用戶》案例,本文再提供1種新的解題思路,合計2種解題思路。

          2.1. 思路1:按時間排序求差值再分組計數(shù)

          才哥上次的解法就是這種思路,回看當(dāng)初的代碼顯得比較稚嫩,今天我們看看小明哥的解法,非常精彩。

          步驟1:篩選空氣質(zhì)量為污染的數(shù)據(jù)

          t = aqi.query('空氣質(zhì)量=="污染"')
          t.sample(5)
          圖4:篩選空氣質(zhì)量污染的數(shù)據(jù)

          步驟2:新增輔助列(輔助列可以不用加到原數(shù)據(jù)t上)

          這里的邏輯大概如下:

          • 輔助排名列(按照時間順序排序)為間隔天數(shù)
          • 然后用時間字段(time)與間隔天數(shù)求差值得到一個日期
          • 如果得到的這個日期相同,則這幾天是連續(xù)污染天
          groupids = pd.to_datetime(aqi.time)-pd.to_timedelta(aqi.time.rank(),unit='d')
          groupids.sample(5)
          圖5:輔助列

          步驟3:分組計數(shù)獲得連續(xù)天數(shù),分組求最小最大值獲得連續(xù) 污染起止日期

          t.groupby(groupids).agg({
              'time'lambda x:f'{x.min()}~{x.max()}'# 求起止日期
              '空氣質(zhì)量':"count"# 求連續(xù)天數(shù)
          }).nlargest(5,'空氣質(zhì)量'# 取 空氣質(zhì)量 字段最大的前5組數(shù)據(jù)
          圖6:解法1的結(jié)果

          以上完整代碼如下:

          t = aqi.query('空氣質(zhì)量=="污染"')
          t.groupby(
              pd.to_datetime(t.time)-pd.to_timedelta(t.time.rank(),unit='d')
                   ).agg(
              {
              'time'lambda x:f'{x.min()}~{x.max()}',
              '空氣質(zhì)量':"count",
              }
          ).nlargest(5,'空氣質(zhì)量')

          2.2. 思路2:比對相鄰兩天空氣質(zhì)量標(biāo)記

          思路2有兩種解法,其一是利用循環(huán)創(chuàng)建輔助列,其二是利用shift和cumsum創(chuàng)建輔助列,具體我們可以往下看。

          解法1:利用循環(huán)創(chuàng)建輔助列

          • 創(chuàng)建一個輔助列,輔助列的值按照以下思路創(chuàng)建函數(shù)獲取
          • 如果空氣質(zhì)量為優(yōu)良,則輔助列值+1;若當(dāng)前空氣質(zhì)量和上一日不同,則輔助列值也+1
          • 以上均不滿足,則輔助列值不變
          last = None
          num = 0
          groupids = []
          for v in aqi.空氣質(zhì)量.values:
              if v != last or v != '污染':
                  num += 1
              groupids.append(num)
              last = v

          根據(jù)這個邏輯可以得到輔助列數(shù)據(jù)如下:

          圖7:輔助列值預(yù)覽

          可以發(fā)現(xiàn),按照輔助列分組進行計數(shù)即可獲得連續(xù)污染天數(shù),如上紅色標(biāo)記區(qū)域。

          aqi.groupby(groupids).agg(
              {
              'time'lambda x:f'{x.min()}~{x.max()}',
              '空氣質(zhì)量':"count",
              }
          ).nlargest(5,'空氣質(zhì)量')
          圖8:思路2的解法1結(jié)果

          解法2:利用shift和cumsum創(chuàng)建輔助列

          • 先創(chuàng)建空氣質(zhì)量的shift列,下移動一位
          • 如果shift列和空氣質(zhì)量列相等,則判斷列為0,否則為1
          • 輔助列為判斷列累加求和
          圖9:輔助列創(chuàng)建思路預(yù)覽

          我們也可以發(fā)現(xiàn),按照輔助列分組計數(shù)即可獲取空氣質(zhì)量連續(xù)天數(shù)(優(yōu)良和污染均可),如上紅色區(qū)域。

          (
              aqi.query('空氣質(zhì)量=="污染"'# 這里篩選 污染 天氣
              .groupby((aqi.空氣質(zhì)量.shift() != aqi.空氣質(zhì)量).cumsum()) # 輔助列
              .time.agg(['count','min','max']) # 計數(shù)及獲取日期區(qū)間
              .nlargest(5,'count')
          )
          圖9:思路2的解法2結(jié)果

          按照小明哥的輸出結(jié)果,調(diào)整代碼如下:

          (    aqi.query("空氣質(zhì)量=='污染'")    .groupby((aqi.空氣質(zhì)量 != aqi.空氣質(zhì)量.shift()).cumsum())    .agg(    {        'time': lambda x: f"{x.min()}~{x.max()}",         '空氣質(zhì)量': "count"}    ).nlargest(5, '空氣質(zhì)量'))
          圖10:思路2的解法2小明哥結(jié)果

          以上就是本次全部內(nèi)容,其實我們在日常工作生活中還可能遇到類似場景如:計算用戶連續(xù)登錄天數(shù)、計算用戶連續(xù)付費天數(shù)、計算南方梅雨季節(jié)連續(xù)下雨天數(shù)等等!

          瀏覽 179
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美大屌操逼视频 | 做女人自拍视频在线播放 | 日韩福利在线观看 | 亚洲综合网狼人综合 | 日韩一极片 |