1
votes

Comment puis-je baliser une certaine valeur en fonction de la valeur des lignes précédentes dans DataFrame?

Les données ressemblent à ceci:

Ctgr|subctgr
  A |  A
  B |  A
  B |  A
  C |  A
  D |  D
  E |  D
  F |  D

Le résultat que je recherche est:

Ctgr
A
B
B
C
D
E
F

C'est-à-dire que subctgr est déterminé par la valeur de la première ligne de chaque "groupe".
Cependant, je ne sais pas comment distinguer chaque "groupe" en python, bien qu'ils soient séparés par une valeur NaN.


0 commentaires

3 Réponses :


0
votes

Cela peut être fait en utilisant la méthode pandas apply , je suppose que si le caractère est alors vous voulez mettre 'A' code>, sinon 'D' .

En supposant que le nom du dataframe est df :

  Ctgr subctgr
0    A       A
1    B       A
2    B       A
3    C       A
4    D       D
5    E       D
6    F       D

La sortie serait comme:

df['subctgr'] = df['Ctgr'].apply(lambda x: 'A' if x<='C' else 'D')


0 commentaires

0
votes

Voici une façon de faire:

# create a group counter column
df['Counter'] = df['Ctgr'].isna().cumsum()

# drop NA
df2 = df[df['Ctgr'].notna()].reset_index(drop=True)

# join cols
def solve(f):
    # filter data
    f['col'] = f['Ctgr'].apply(lambda x: x + '|' + f['Ctgr'].iloc[0])
    return f

df2 = df2.groupby('Counter').apply(solve)

  Ctgr  Counter  col
0    A        0  A|A
1    B        0  B|A
2    B        0  B|A
3    C        0  C|A
4    D        1  D|D
5    E        1  E|D
6    F        1  F|D


0 commentaires

1
votes

Premier test des lignes manquantes en Series.isna , puis obtenez les premières valeurs des groupes en les comparant avec Series.shift ed valeurs du masque et créer une nouvelle colonne remplie par les valeurs précédentes par ffill . Dernière nouvelle colonne définie par numpy.where code > :

print (df.assign(m = df['Ctgr'].isna(),
                 mask = m.ne(m.shift()),
                 first = df['Ctgr'].where(m.ne(m.shift())),
                 ffill = df['Ctgr'].where(m.ne(m.shift())).ffill(),
                 subctgr = np.where(m,np.nan,df['Ctgr'].where(m.ne(m.shift())).ffill())))
  Ctgr      m   mask first ffill subctgr
0    A  False   True     A     A       A
1    B  False  False   NaN     A       A
2    B  False  False   NaN     A       A
3    C  False  False   NaN     A       A
4  NaN   True   True   NaN     A     NaN
5    D  False   True     D     D       D
6    E  False  False   NaN     D       D
7    F  False  False   NaN     D       D

Détails :

#for test missing values
m = df['Ctgr'].isna()
#for test emtsy strings
#m = df['Ctgr'].eq('')
df['subctgr'] = np.where(m,np.nan,df['Ctgr'].where(m.ne(m.shift())).ffill())
print (df)
  Ctgr subctgr
0    A       A
1    B       A
2    B       A
3    C       A
4  NaN     NaN
5    D       D
6    E       D
7    F       D


0 commentaires