Pandalar: Bir kayıt sürece, hafta sonları hariç haftanın en yüksek gününü seçin

oy
0

Ben tarihleri ​​ile bir dataframe var ve (varsa, bu nedenle cuma) Ben hafta sonları hariç her hafta en yüksek tarihi seçmek istiyorum, hiçbir Pazartesi-Cuma veri olmadıkça ve Cumartesi / Pazar tek bulunmakta.

örnek verileri böyle kurulum olabilir:

dates = pd.Series(data=['2018-11-05', '2018-11-06', '2018-11-07', '2018-11-08', '2018-11-09',
                        '2018-11-12', '2018-11-13', '2018-11-14', '2018-11-15', '2018-11-17',
                        '2018-11-19',
                        '2018-12-01',
                        ])
nums = np.random.randint(50, 100, 12)
# nums
# array([95, 80, 81, 51, 98, 62, 50, 55, 59, 77, 69])

df = pd.DataFrame(data={'dates': dates, 'nums': nums})
df['dates'] = pd.to_datetime(df['dates'])

kayıtlar istediğim:

  • 2018/11/09 Cuma
  • 2018/11/15 Perşembe (o coz değil 2018/11/17 Cumartesi)
  • 2018/11/19 Pazartesi ve o hafta için tek kaydıdır
  • 2018/12/01 Cumartesi ancak o hafta için tek kaydıdır

Benim şu anki çözüm olduğunu aşağıda cevabını ama ideal ve etrafa çalışmak zorunda bazı sorunları vardır sanmıyorum. Kısaca, bu kadar:

  1. GroupBy hafta: df.groupby(df['dates'].dt.week).apply(some_function)
  2. o hafta için sadece bir kayıt varsa, iade
  3. aksi halde, günde <= Cuma ve geri dönüşü en yüksek / son kayıt seç o

İdeal olarak, Yazmam için bir yol istiyorum:

[latest Mon-Fri record] if [has Mon-Fri record] else [latest Sat-Sun record]
Oluştur 27/11/2018 saat 18:22
kaynak kullanıcı
Diğer dillerde...                            


2 cevaplar

oy
1

Cumartesi ve Pazar düşük öncelik verilir hafta içi, yeni bir hiyerarşisi oluşturun. Sonra sort_valuesbu yeni sıralamasını + groupby+ .tail(1).

import numpy as np

wd_map = dict(zip(np.arange(0,7,1), np.roll(np.arange(0,7,1),-2)))
# {0: 2, 1: 3, 2: 4, 3: 5, 4: 6, 5: 0, 6: 1}
df = df.assign(day_mapped = df.dates.dt.weekday.map(wd_map)).sort_values('day_mapped')

df.groupby(df.dates.dt.week).tail(1).sort_index()

Çıktı

        dates  nums  day_mapped
4  2018-11-09    57           6
8  2018-11-15    83           5
10 2018-11-19    96           2
11 2018-12-01    66           0

Veri birden yıllar kapsıyorsa, her iki Gruba gerekir Year+ week.

Cevap 27/11/2018 saat 18:35
kaynak kullanıcı

oy
0

Bir haftalık GroupBy kullanılacak gerekir hafta, geçerli en yüksek kayıt seçmek için bir fonksiyon yazdım:

def last_valid_report(recs):
    if len(recs) == 1:
        return recs
    recs = recs.copy()
    # recs = recs[recs['dates'].dt.weekday <= 4].nlargest(1, recs['dates'].dt.weekday)  # doesn't work
    recs['weekday'] = recs['dates'].dt.weekday  # because nlargest() needs a column name
    recs = recs[recs['weekday'] <= 4].nlargest(1, 'weekday')
    del recs['weekday']
    return recs
    # could have also done:
    # return recs[recs['weekday'] <= 4].nlargest(1, 'weekday').drop('weekday', axis=1)

Doğru gruplarla bu çağrılması, alıyorum:

In [155]: df2 = df.groupby(df['dates'].dt.week).apply(last_valid_report)

In [156]: df2
Out[156]:
              dates  nums
dates
45    4  2018-11-09    63
46    8  2018-11-15    90
47    10 2018-11-19    80
48    11 2018-12-01    94

Bununla sorunlardan birkaçı:

  1. Ben koymazsanız recs.copy(), benim hemenValueError: Shape of passed values is (3, 12), indices imply (3, 4)

  2. pandalarnlargest sütun adları değil, bir ifade kullanacaktır.

    • bu yüzden / işlev ve damla ilave bir sütun oluşturun dönmeden önce silmeniz gerekir. Ayrıca orijinal df bu oluşturup sonra düşebilir .apply().
  3. Fazladan bir indeks sütunlu, 'büyük' alıyorum gelen GroupBy + uygulamak ve olması gereken açıkça düştü :

    In [157]: df2.index = df2.index.droplevel(); df2
    Out[157]:
            dates  nums
    4  2018-11-09    63
    8  2018-11-15    90
    10 2018-11-19    80
    11 2018-12-01    94
    
  4. Cumartesi ve Pazar verilerine (2 gün) ile rekor alırsam, eğer bir çek eklemem gerekiyor recs[recs['weekday'] <= 4]boş ve sadece kullanmak .nlargest(1, 'weekday')filtreleyerek olmadan weekday <= 4; ancak bu söz konusu noktaya yanında bulunuyor.

Cevap 27/11/2018 saat 18:22
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more