web-dev-qa-db-fra.com

Comment remplir les valeurs Nan de dataframe avec une liste vide [] dans les pandas?

Voici mon dataframe:

          date                          ids
0     2011-04-23  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...
1     2011-04-24  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...
2     2011-04-25  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...
3     2011-04-26  Nan
4     2011-04-27  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...
5     2011-04-28  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,...

Je veux remplacer Nan par []. Comment faire ça? Fillna ([]) n'a pas fonctionné. J'ai même essayé replace(np.nan, []) mais cela donne une erreur:

 TypeError('Invalid "to_replace" type: \'float\'',)
28
ALH

Vous pouvez d'abord utiliser loc pour localiser toutes les lignes qui ont un nan dans la colonne ids, puis parcourir ces lignes en utilisant at pour définir leurs valeurs à une liste vide:

for row in df.loc[df.ids.isnull(), 'ids'].index:
    df.at[row, 'ids'] = []

>>> df
        date                                             ids
0 2011-04-23  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
1 2011-04-24  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
2 2011-04-25  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
3 2011-04-26                                              []
4 2011-04-27  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
5 2011-04-28  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
14
Alexander

Mon approche est similaire à celle de @ hellpanderrr, mais teste plutôt la liste plutôt que d'utiliser isnan:

df['ids'] = df['ids'].apply(lambda d: d if isinstance(d, list) else [])

J'ai essayé à l'origine d'utiliser pd.isnull (ou pd.notnull) mais, quand on lui donne une liste, cela retourne la nullité de chaque élément.

17
Nick Edgar

Après beaucoup de grattage de tête, j'ai trouvé cette méthode qui devrait être la plus efficace (pas de boucle, pas d'application), en l'assignant simplement à une tranche:

isnull = df.ids.isnull()

df.loc[isnull, 'ids'] = [ [[]] * isnull.sum() ]

L'astuce consistait à construire votre liste de [] De la bonne taille (isnull.sum()), et puis l'enfermer dans une liste: la valeur que vous affectez est un 2D tableau (1 colonne, isnull.sum() lignes) contenant des listes vides comme éléments.

10
PlasmaBinturong

Sans affectations:

1) En supposant que nous n'avons que des flottants et des entiers dans notre trame de données

import math
df.apply(lambda x:x.apply(lambda x:[] if math.isnan(x) else x))

2) Pour toute trame de données

import math
def isnan(x):
    if isinstance(x, (int, long, float, complex)) and math.isnan(x):
        return True

df.apply(lambda x:x.apply(lambda x:[] if isnan(x) else x))
1
hellpanderr

C'est probablement plus rapide, une solution de revêtement:

df['ids'].fillna('DELETE').apply(lambda x : [] if x=='DELETE' else x)
0
botivegh

Peut-être plus dense:

df['ids'] = [[] if type(x) != list else x for x in df['ids']]
0
keramat

Une autre solution utilisant numpy:

df.ids = np.where(df.ids.isnull(), pd.Series([[]]*len(df)), df.ids)

Ou en utilisant combine_first:

df.ids = df.ids.combine_first(pd.Series([[]]*len(df)))
0
Allen