J'ai un dataframe Pandas suivant, où je veux changer une valeur de colonne «fmc» basée sur les colonnes «time», «samples» et «uid».

Le concept est le suivant:

Pour le même date, if df.samples == 'C' & df.uid == 'Plot1', puis la valeur de ligne correspondante de fmc * 0.4

De même pour le même date, if df.samples == 'C' and df.uid == 'Plot2', puis la valeur de ligne correspondante de fmc*0.8

Pour le même date, if df.samples == 'E' & df.uid == 'Plot1', puis la valeur de ligne correspondante de fmc * 0.4

De même pour le même date, if df.samples == 'E' and df.uid == 'Plot2', puis la valeur de ligne correspondante de fmc*0.15

Pour le même date, if df.samples == 'ns' & df.uid == 'Plot1', puis la valeur de ligne correspondante de fmc * 0.2

De même pour le même date, if df.samples == 'ns' and df.uid == 'Plot2', puis la valeur de ligne correspondante de fmc*0.05

Je suis nouveau sur python, donc je m'excuse si je n'ai pas bien expliqué et s'il vous plaît laissez-moi savoir si vous avez besoin de plus de précisions.

       time        samples    uid                 fmc
0  2015-10-11        C       Plot1              98.226352
1  2015-10-11        C       Plot2             132.984817
2  2015-10-11        E       Plot1             114.147964
3  2015-10-11        E       Plot2             110.083699
4  2015-10-11        ns      Plot1             113.258977
5  2015-10-11        ns      Plot2             113.768023
6  2015-10-19        C       Plot1             118.503214
7  2015-10-19        E       Plot1             108.733209
8  2015-10-19        ns      Plot1              59.316977
9  2015-10-27        C       Plot1             104.977531
10 2015-10-27        C       Plot2             121.213887
11 2015-10-27        E       Plot1             129.575670
12 2015-10-27        E       Plot2             118.639048
13 2015-10-27        ns      Plot1             103.581065
14 2015-10-27        ns      Plot2             102.278469
15 2015-11-17        C       Plot1             103.820689
16 2015-11-17        C       Plot2             117.333382
17 2015-11-17        E       Plot1             143.418932
18 2015-11-17        E       Plot2             160.342155
19 2015-11-17        ns      Plot1              89.890484
2
Sher 25 févr. 2021 à 03:08

4 réponses

Meilleure réponse

Ce code:

import pandas as pd
data = [
    ['2015-10-11', 'C', 'Plot1',  98.226352 ],
    ['2015-10-11', 'C', 'Plot2', 132.984817 ],
    ['2015-10-11', 'E', 'Plot1', 114.147964 ],
    ['2015-10-11', 'E', 'Plot2', 110.083699 ],
    ['2015-10-11', 'ns', 'Plot1', 113.258977 ],
    ['2015-10-11', 'ns', 'Plot2', 113.768023 ],
    ['2015-10-19', 'C', 'Plot1', 118.503214 ],
    ['2015-10-19', 'E', 'Plot1', 108.733209 ],
    ['2015-10-19', 'ns', 'Plot1',  59.316977 ],
    ['2015-10-27', 'C', 'Plot1', 104.977531 ],
    ['2015-10-27', 'C', 'Plot2', 121.213887 ],
    ['2015-10-27', 'E', 'Plot1', 129.575670 ],
    ['2015-10-27', 'E', 'Plot2', 118.639048 ],
    ['2015-10-27', 'ns', 'Plot1', 103.581065 ],
    ['2015-10-27', 'ns', 'Plot2', 102.278469 ],
    ['2015-11-17', 'C', 'Plot1', 103.820689 ],
    ['2015-11-17', 'C', 'Plot2', 117.333382 ],
    ['2015-11-17', 'E', 'Plot1', 143.418932 ],
    ['2015-11-17', 'E', 'Plot2', 160.342155 ],
    ['2015-11-17', 'ns', 'Plot1',  89.890484]
]

df = pd.DataFrame(columns=['time', 'samples', 'uid', 'fmc'], data=data)

print (df.head(10))

df['result'] = df.apply(
                lambda item:
                   (item.fmc * 0.4) if item.samples == 'C' and item.uid == 'Plot1' else \
                   (item.fmc * 0.8) if item.samples == 'C' and item.uid == 'Plot2' else \
                   (item.fmc * 0.4) if item.samples == 'E' and item.uid == 'Plot1' else \
                   (item.fmc * 0.15)if item.samples == 'E' and item.uid == 'Plot2' else \
                   (item.fmc * 0.2) if item.samples == 'ns'and item.uid == 'Plot1' else \
                   (item.fmc * 0.05)if item.samples == 'ns'and item.uid == 'Plot2' else None,
                axis=1
            )

print(df.head(10))

Devrait produire cette sortie:

         time samples    uid         fmc
0  2015-10-11       C  Plot1   98.226352
1  2015-10-11       C  Plot2  132.984817
2  2015-10-11       E  Plot1  114.147964
3  2015-10-11       E  Plot2  110.083699
4  2015-10-11      ns  Plot1  113.258977
5  2015-10-11      ns  Plot2  113.768023
6  2015-10-19       C  Plot1  118.503214
7  2015-10-19       E  Plot1  108.733209
8  2015-10-19      ns  Plot1   59.316977
9  2015-10-27       C  Plot1  104.977531
         time samples    uid         fmc      result
0  2015-10-11       C  Plot1   98.226352   39.290541
1  2015-10-11       C  Plot2  132.984817  106.387854
2  2015-10-11       E  Plot1  114.147964   45.659186
3  2015-10-11       E  Plot2  110.083699   16.512555
4  2015-10-11      ns  Plot1  113.258977   22.651795
5  2015-10-11      ns  Plot2  113.768023    5.688401
6  2015-10-19       C  Plot1  118.503214   47.401286
7  2015-10-19       E  Plot1  108.733209   43.493284
8  2015-10-19      ns  Plot1   59.316977   11.863395
9  2015-10-27       C  Plot1  104.977531   41.991012

Process finished with exit code 0

Inspiré par df.apply, en utilisant axis=1, et en passant une fonction lambda contenant l'ensemble complet des conditions, vous aurez les valeurs attendues dans la colonne result.

La fonction apply passera les colonnes de la trame de données (car axis=1), à la fonction lambda comme item pour chaque enregistrement de la série de valeurs. La fonction lambda renvoie également la valeur result correspondante pour chaque enregistrement / élément donné de la série, nous n'avons donc pas à nous soucier de la correspondance des valeurs de date / d'index.

Référence pour pandas.DataFrame.apply ici .

1
Rikki 25 févr. 2021 à 01:17

Vous devriez pouvoir utiliser itertuples () pour gérer celui-ci, ce qui vous permet de parcourir les lignes d'un bloc de données. Je ne suis pas sûr de ce que vous entendez par «à la même date», étant donné que vos critères d'échantillonnage et de uid couvrent toutes les dates.

fmc_adjusted = []
for row in df.itertuples():
    if df.samples == 'C' and df.uid == 'Plot1':
        fmc_adjusted.append(row[4]*0.4)
    if df.samples == 'C' and df.uid == 'Plot2':
        fmc_adjusted.append(row[4]*0.15)

... et ainsi de suite pour vos différents critères.

J'aime garder mes colonnes au cas où je devrais y faire référence plus tard. Si vous souhaitez créer une nouvelle colonne:

df['fmc_adjusted'] = fmc_adjusted

Si vous souhaitez remplacer votre colonne fmc:

df['fmc'] = fmc_adjusted

Il existe probablement des moyens plus rapides et plus ordonnés de le faire, mais je n'en suis pas conscient.

0
BigHeadEd 25 févr. 2021 à 00:36

Créez une fonction qui prend des caractéristiques (colonnes) et renvoie un résultat basé sur des conditions.

def arrange_stuff(col2, col3, col4):
   if col2 == 'C' & col3 == 'Plot1'
      return col4*0.4
   elif ...
      return ...

Créez ensuite une nouvelle fonctionnalité en appliquant la fonction comme suit:

df['fmc_new'] = df(lambda x: arrange_stuff(x['samples'],x['uid'],x['fmc']), axis=1)

Si vous n'avez pas besoin de la colonne fmc d'origine, vous pouvez simplement la déposer et renommer fmc_new, ou peut-être l'assigner directement en premier lieu.

0
delimiter 25 févr. 2021 à 00:29

Créer des requêtes

C1=(df.samples.eq('C')&df.uid.eq('Plot1'))|(df.samples.eq('E')&df.uid.eq('Plot1'))
C2=df.samples.eq('C')&df.uid.eq('Plot2')

C4=df.samples.eq('E')&df.uid.eq('Plot2')
C5=df.samples.eq('ns')&df.uid.eq('Plot1')
C6=C5=df.samples.eq('ns')&df.uid.eq('Plot2')

Mettre les requêtes dans une liste

conditions=[C1,C2,C4,C5,C6]

Inscrire le résultat correspondant à chaque requête dans la liste

MULT=[0.4,0.8,0.15,0.2,0.05]

Créez une colonne temporaire et remplissez-la à l'aide de np.select (condition, résultat)

df['fmc1']=np.select(conditions, MULT,df.fmc)

Multiplier le résultat avec fmc et supprimer la colonne temporaire

df=df.assign(fmc=df['fmc']*df['fmc1']).drop('fmc1',1)
0
wwnde 25 févr. 2021 à 00:22