4 votes

Obtenir la valeur de la première occurrence dans chaque colonne

Voici mon df. Je veux obtenir la première valeur dans chaque colonne qui contient (F)

>>> d = {0: ['1', '2(F)', '6', '8', '5'], 
    1: ['8(F)', '6', '8', '4(F)', '4'], 
    2: ['1', '6', '8(F)', '4(F)', '5'],
    3: ['1', '8', '8', '1', '5']}
>>> df = pd.DataFrame(data=d)
>>> df
      0     1     2  3
0     1  8(F)     1  1
1  2(F)     6     6  8
2     6     8  8(F)  8
3     8  4(F)  4(F)  1
4     5     4     5  5

Et le résultat devrait ressembler à ceci

0    2(F)
1    8(F)
2    8(F)
3     NaN

Mais lorsque j'ai utilisé le code ci-dessous, j'ai reçu des erreurs

>>> mask = df.apply(lambda x: x.str.contains('F'))
>>> a = mask.idxmax().where(mask.any())
>>> print(df[a])

KeyError: '[nan] not in index'

5voto

W-B Points 94428

Voici un moyen

mask = df.applymap(lambda x: '(F)' in x)

df[mask].bfill().iloc[0,]
Out[624]: 
0    2(F)
1    8(F)
2    8(F)
3     NaN
Name: 0, dtype: object

4voto

jezrael Points 290608

Utiliser l'indexation numpy pour obtenir des valeurs par idxmax et enfin ajouter where :

mask = df.apply(lambda x: x.str.contains('F', na=False))
a = mask.idxmax()   
s = pd.Series(df.values[a, a.index]).where(mask.any())
print(s)
0    2(F)
1    8(F)
2    8(F)
3     NaN
dtype: object

Une autre solution avec reshape by DataFrame.stack en filtrant et en obtenant la première valeur par GroupBy.first enfin, ajouter les valeurs inexistantes par Series.reindex :

s = df.stack()
s = s[s.str.contains('F', na=False)].groupby(level=1).first().reindex(df.columns)
print (s)
0    2(F)
1    8(F)
2    8(F)
3     NaN
dtype: object

4voto

piRSquared Points 159

applymap , lookup

mask = df.applymap(lambda x: '(F)' in x)
vals = df[mask].lookup(mask.idxmax(), df.columns)
pd.Series(vals, df.columns)

0    2(F)
1    8(F)
2    8(F)
3     NaN
dtype: object

Variante Numpy

Sur-mesure

from numpy.core.defchararray import find

v = df.values.astype(str)
m = find(v, '(F)') >= 0
i = m.argmax(0)
j = np.arange(v.shape[1])

pd.Series(np.where(m[i, j], v[i, j], np.nan), df.columns)

0voto

hacker315 Points 1704

Voici, une seule ligne mais elle ne donne pas la réponse pour la 4ème ligne :

df.replace("\d$", np.nan, regex=True).dropna(how='all', axis=1).apply(lambda x: x.dropna().iloc[0], 0)

Il efface tous les éléments autres que \F puis pour chaque colonne, il trouve les premiers éléments non vides.

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