0
votes

Faire de la 53e et de la 1e semaine la même semaine à partir du dimanche

Bonjour, j'ai les données suivantes:
index, Jour de la semaine, Semaine no, Fécha

totals[(totals['Fecha'].dt.month==1) & (totals['Fecha'].dt.day==1) & (totals['Fecha'].dt.year==i)]

Je voudrais:
-la semaine qui contient le premier janvier pour être la semaine n ° 1
-pour que les semaines commencent le dimanche
-d'avoir la semaine n ° 1 comme une semaine complète de 7 jours, c'est-à-dire les 29, 30 et 31 décembre pour obtenir également la semaine n ° 1.
-pour que cela fonctionne aussi quand j'ai beaucoup d'années dans cet ensemble de données.

Cette année-là, cela signifie changer tous les 53 en 1 mais je pense qu'il y aura peut-être d'autres années où cela ne fonctionnera pas. Donc, pour avoir une règle générale, j'ai réalisé que si le premier janvier tombe un dimanche, je n'ai rien à changer, alors j'ai pensé à vérifier cela pour chaque année et si le premier janvier ne tombe pas un dimanche pour changer toutes les semaines entre le dimanche précédent et ce dimanche en 1. Une autre option à laquelle j'ai pensé est de savoir à quelle semaine le dimanche précédent a, puis de changer toutes les semaines de cette année avec le même numéro que le dimanche précédent, à 1. Pour les deux, je devrais faire une condition dans un df pour filtrer uniquement certaines lignes, mais comment puis-je faire cela lorsque je ne veux afficher qu'une colonne de ce df? Signification si je le ferais:

360      Friday       52 2019-12-27
361    Saturday       52 2019-12-28
362      Sunday       53 2019-12-29
363      Monday       53 2019-12-30
364     Tuesday       53 2019-12-31
365   Wednesday        1 2020-01-01
366    Thursday        1 2020-01-02
367      Friday        1 2020-01-03
368    Saturday        1 2020-01-04
369      Sunday        2 2020-01-05
370      Monday        2 2020-01-06

alors cela afficherait toutes les colonnes dans les totaux alors que je voudrais et ces conditions et pour voir uniquement la colonne 'Jour de la semaine'.

Alors comment pourrais-je faire ça et aussi, tout cela me semble super compliqué. Y a-t-il un moyen plus simple / plus efficace que j'ai négligé?

Merci!


4 Réponses :


0
votes

Vous pouvez utiliser l'opérateur mod . Cela vous donnera le reste après avoir divisé par un nombre donné. Pour cela, 52% 52 = 0 et 0% 52 = 0 . Mod ne fonctionne vraiment que lorsque vous commencez à compter à partir de 0, vous devrez donc moins un premier, voir ci-dessous:

my_week = 53
my_bounded_week = ((my_week - 1) % 52) + 1
# First minus one to make the series start at 0.
# Then add one after the mod to make the series start at 1

print(my_bounded_week)
# prints 1


3 commentaires

Merci. N'est-ce pas la même chose que de remplacer les 53 par 1? Je ne sais pas si cela fonctionnera, car s'il y aura une année où février a 29 jours ET le premier janvier tombe un samedi, ce qui signifie que le 2 janvier est un dimanche et la semaine 2, cette année aura 54 semaines Non, donc les 53 doivent rester tels quels et seuls les 54 passent à 1. Confus!


Dans ce cas, vous devrez utiliser le mod du nombre maximum de semaines - 1 . Donc, une fois que vous avez terminé de calculer les semaines, revenez en arrière dans l'année en modifiant la dernière semaine


Cela ne fonctionnerait pas non plus parce que si le premier janvier est un dimanche, vous voudriez laisser toutes les dates de décembre comme la dernière semaine de l'année.



0
votes

Utilisez le package datetime comme décrit dans cette réponse StackOverflow: Comment puis-je trouver les numéros de semaine avec des semaines commençant le dimanche en Python?


1 commentaires

J'utilise ce package et c'est ainsi que j'ai obtenu la colonne actuelle «Semaine non», mais comme vous le voyez, il s'avère un peu différent de ce dont j'ai besoin. Si vous connaissez une fonction qui transforme tous les jours de cette semaine en 1 (même ceux de décembre), j'aimerais en entendre parler. Merci!



0
votes

Il semble que vous ayez besoin de votre propre calendrier professionnel personnalisé, nous pouvons utiliser une petite fonction pour en créer un.

En supposant que vous créez un calendrier commençant le premier jour calendaire de chaque année civile, cela fonctionnera. p>

Une mise en garde est que je n'ai pas écrit ceci depuis plusieurs années, je vous laisse le soin :)

Utilisation

def business_cal(start,end):
    """
    Function that returns a calendar year given a start and end date.
    Constrains - week must start on Sunday if 01/01/2020 is not Sunday,
    we take the last Sunday of the previous year.
    """
    start_date = pd.to_datetime(start)
    
    if start_date.weekday() != 6:
        start_date = start_date - pd.DateOffset(days=(start_date.weekday() + 1))
    else:
        start_date


    dates = pd.date_range(start_date,end,freq='7D')
    
    df = pd.DataFrame(dates,columns=['date'])
    # grab week numbers.
    df['weeks'] = df.index + 1 
    df1 = df.set_index('date').resample('D').ffill().reset_index()
    
    df1['dayofmonth'] = df1['date'].dt.day
    df1['dayofweek'] = df1['date'].dt.dayofweek
    df1['daynameofweek'] = df1['date'].dt.day_name()
    return df1

Fonction.

df = business_cal('01-01-2019','01-01-2020')

print(df.head(5))

        date  weeks  dayofmonth  dayofweek daynameofweek
0 2018-12-30      1          30          6        Sunday
1 2018-12-31      1          31          0        Monday
2 2019-01-01      1           1          1       Tuesday
3 2019-01-02      1           2          2     Wednesday
4 2019-01-03      1           3          3      Thursday


0 commentaires

1
votes

C'est donc ce que j'ai trouvé à la fin. Quel est le niveau des performances?

totals['Fecha']=pd.to_datetime(totals['Fecha'], format='%d/%m/%Y') #change type to datetime
totals['Day of week']=totals['Fecha'].dt.weekday_name   #create day of week 'Sunday, Monday, etc'
totals['Week no']=totals['Fecha'].dt.strftime('%U').astype(int)+1 #create week no's with Sunday as first day of week

for i in set(totals['Fecha'].dt.year):
    if i!=2019: #because for the first year we don't have a previous end of year
        first_day_of_year=str(i)+'-01-01' 
        # if there are any rows where the day of the week of the first day of the year equals 'Sunday'
        if any(totals['Day of week'].where(totals['Fecha']==first_day_of_year)!='Sunday'):

        # then for the year before, change all the last week no's to one
            last_week=max(totals['Week no'].where(totals['Fecha'].dt.year==i-1))
            totals.loc[(totals['Week no']==last_week)&(totals['Fecha'].dt.year==i-1), 'Week no']=1

print(totals[['Day of week', 'Week no', 'Fecha']])


0 commentaires