2 votes

Boucle dans un cadre de données pour vérifier la correspondance d'une chaîne de caractères.

C'est la première fois que je pose une question et je suis un débutant en python, j'espère donc que je la pose correctement.

Je dois parcourir en boucle toutes les lignes d'un cadre de données, en vérifiant si une chaîne de caractères correspond à une colonne. S'il y a une correspondance, je veux insérer une date dans une nouvelle colonne, sinon j'utilise une autre date.

J'ai besoin d'itérer dans les lignes car chaque fois que la condition est remplie, je veux avancer la date d'un jour.

Pour l'instant, j'essaie simplement de m'assurer que la correspondance des chaînes de caractères fonctionne et que j'insère deux chaînes de caractères différentes en fonction du résultat de la correspondance. Le problème est que mes conditions semblent ne jamais être remplies. Je ne vois pas où le problème se situe.

Mon code jusqu'à présent est

for index in df.index:
    if df.loc[index, 'time'] == '00:00':
        df['date'] = "wooo"
    else:
        df['date'] = "blah"

Le résultat que je vois est dans l'image ci-dessous. Comme vous pouvez le constater, la ligne qui correspond à la condition n'est pas récupérée.

enter image description here

1voto

Pranav Hosangadi Points 5045

df['date'] = "wooo" définit la colonne entière à "wooo" ce qui, j'en suis sûr, n'est pas votre intention. Vous devriez juste mettre cette rangée date colonne

for index in df.index:
    if df.loc[index, 'time'] == '00:00':
        df.loc[index, 'date'] = "wooo"
    else:
        df.loc[index, 'date'] = "blah"

Mieux encore, utilisez l'indexation logique et définissez plusieurs lignes à la fois au lieu d'itérer sur les lignes et de définir chaque valeur individuellement :

df['date'] = 'blah'                 # Set everything to blah
zero_rows = df['time'] == '00:00'   # Find the rows where time is 00:00
df.loc[zero_rows, 'date'] = 'wooo'  # Set these rows to wooo

Par exemple, avec

df = pd.DataFrame([['00:00', 2, 3], ['00:01', 5, 6], ['00:02', 8, 9], ['00:00', 10, 11]], columns=['time', 'b', 'c'])

on obtient :

    time   b   c  date
0  00:00   2   3  wooo
1  00:01   5   6  blah
2  00:02   8   9  blah
3  00:00  10  11  wooo

Re. votre commentaire :

Le problème avec l'indexation logique est qu'en fin de compte, j'essaie d'attribuer une date qui compte en avant au début de chaque nouveau jour (heure = 00:00), donc jusqu'à ce qu'un 00:00 soit trouvé, insérer la date du jour dans chaque ligne. Jusqu'à ce qu'un 00:00 soit trouvé, insérer la date du jour dans chaque ligne. Une fois trouvée, insérer aujourd'hui+1 et continuer jusqu'à ce qu'elle soit trouvée à nouveau, puis insérer aujourd'hui+2 etc. Le nombre de lignes jusqu'à ce que le premier 00:00 soit trouvé varie en fonction du moment où le cadre de données est créé.

Ceci est facile à mettre en œuvre. Commençons par un cadre de données plus long :

df = pd.DataFrame([['00:00', 2, 3], ['12:00', 5, 6], ['00:00', 8, 9], ['12:00', 10, 11], ['00:00', 18, 19], ['12:00', 110, 111], ['00:00', 28, 29], ['12:00', 210, 211]], columns=['time', 'b', 'c'])

Sortons toutes les colonnes avec time == '00:00' .

zero_rows = df['time'] == '00:00'
midnights = df.loc[zero_rows, :]

    time   b   c
0  00:00   2   3
2  00:00   8   9
4  00:00  18  19
6  00:00  28  29

Maintenant, créez une nouvelle colonne 'increment' et le remplir avec nan . Ensuite, ne remplissez que les valeurs de minuit avec des chiffres :

if df.iloc[0]['time'] == '00:00':
    start_increment = 0 # First row is midnight, so we start with an increment of zero
else:
    start_increment = 1 # First row is not midnight, so the first midnight row has an increment of 1

df['increment'] = pd.NA
df.loc[midnights.index, 'increment'] = range(start_increment, len(midnights)+start_increment)

    time    b    c increment
0  00:00    2    3         0
1  12:00    5    6      <NA>
2  00:00    8    9         1
3  12:00   10   11      <NA>
4  00:00   18   19         2
5  12:00  110  111      <NA>
6  00:00   28   29         3
7  12:00  210  211      <NA>

Ensuite, nous pouvons utiliser ffill() pour remplir les valeurs de la colonne d'incrémentation qui sont NA .

df['increment'].ffill(inplace=True)

    time    b    c  increment
0  00:00    2    3          0
1  12:00    5    6          0
2  00:00    8    9          1
3  12:00   10   11          1
4  00:00   18   19          2
5  12:00  110  111          2
6  00:00   28   29          3
7  12:00  210  211          3

Tout NA qui restent étaient antérieurs au premier minuit, ils doivent donc être des zéros :

df['increment'].fillna(0, inplace=True)

Maintenant, nous voulons ajouter une colonne 'date' qui a une valeur de today + increment jours. Pour ce faire, nous convertissons d'abord le increment colonne à pd.TimeDelta :

df['increment'] = pd.to_timedelta(df['increment'], unit='D')

    time    b    c increment
0  00:00    2    3    0 days
1  12:00    5    6    0 days
2  00:00    8    9    1 days
3  12:00   10   11    1 days
4  00:00   18   19    2 days
5  12:00  110  111    2 days
6  00:00   28   29    3 days
7  12:00  210  211    3 days

Enfin, ajoutez la date du jour dans la colonne d'incrémentation :

import datetime
df['date'] = datetime.datetime.today() + df['increment']

    time    b    c increment       date
0  00:00    2    3    0 days 2022-02-15
1  12:00    5    6    0 days 2022-02-15
2  00:00    8    9    1 days 2022-02-16
3  12:00   10   11    1 days 2022-02-16
4  00:00   18   19    2 days 2022-02-17
5  12:00  110  111    2 days 2022-02-17
6  00:00   28   29    3 days 2022-02-18
7  12:00  210  211    3 days 2022-02-18

0voto

hc_dev Points 2428

Vous pouvez utiliser apply avec un Expression ternaire pythonique à l'intérieur d'un lambda.

Essayez dans le shell Python :

>>> import pandas as pd
>>> df = pd.DataFrame([['00:00', 2, 3], ['00:01', 5, 6], ['00:02', 8, 9], ['00:00', 10, 11]], columns=['time', 'b', 'c'])
>>> df['date'] = df.time.apply(lambda t: 'wooo' if t == '00:00' else 'blah')
>>> df
    time   b   c  date
0  00:00   2   3  wooo
1  00:01   5   6  blah
2  00:02   8   9  blah
3  00:00  10  11  wooo

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X