Pandas: Lors de l'ajout d'une série à un DataFrame avec un index différent, la série est transformée en tous les NaN

Créé le 6 déc. 2011  ·  9Commentaires  ·  Source: pandas-dev/pandas

Exemple concret :

>>> df
               RP/Rsum  P.value
ID                             
A_23_P42353    17.8     0      
A_23_P369994   15.91    0      
A_33_P3262440  436.7    0.0005 
A_32_P199429   18.97    0      
A_23_P256724   22.24    0      
A_33_P3394689  24.24    0      
A_33_P3403117  27.14    0      
A_24_P252364   28.56    0      
A_23_P99515    31.82    0      
A_24_P261750   31.46    0 

>>> df.dtypes
RP/Rsum    float64
P.value    float64

>>> ids = pandas.Series(['51513', '9201', np.nan, np.nan, '8794', '6530', '7025', '4897', '84935', '11081'])
>>> df["test"] = ids
>>> df
               RP/Rsum  P.value  test
ID                                   
A_23_P42353    17.8     0        NaN 
A_23_P369994   15.91    0        NaN 
A_33_P3262440  436.7    0.0005   NaN 
A_32_P199429   18.97    0        NaN 
A_23_P256724   22.24    0        NaN 
A_33_P3394689  24.24    0        NaN 
A_33_P3403117  27.14    0        NaN 
A_24_P252364   28.56    0        NaN 
A_23_P99515    31.82    0        NaN 
A_24_P261750   31.46    0        NaN 
>>> df.dtypes
RP/Rsum    float64
P.value    float64
test       object

Cela se produit également avec les objets flottants et autres. Je ne sais pas quel est le déclencheur.

Commentaire le plus utile

La série reçoit un indice implicite 0, ..., N-1 lorsque vous n'en fournissez pas un - c'est donc exactement le comportement auquel je m'attendrais. Si data était un ndarray brut ou une liste, cela ne se produirait pas. Donc le fait que lorsque vous faites :

df[col] = series

et il conforme la série exactement à l'index de df , c'est une fonctionnalité et pas un bug :) donc

df['test'] = ids.values

fonctionnerait bien dans ton exemple

Tous les 9 commentaires

Je me demande si c'est lié à ce problème que j'ai trouvé aussi ce matin :

>>> df = pandas.DataFrame(index=[1,2,3,4])
>>> df["test"] = pandas.Series(["B", "fdf", "344", np.nan])
>>> df["test2"] = ["B", "fdf", "344", np.nan]
>>> df   test  test2
1  fdf   B    
2  344   fdf  
3  NaN   344  
4  NaN   nan  

Cela ressemble à une sorte d'erreur aléatoire pour moi.

Des recherches plus poussées mènent à l'appel à Series.reindex lors de la définition d'éléments comme étant le coupable :

>>> data 
0    B
1    fdf
2    344
3    NaN

>>>  df.index = ["A", "B", "C", "D"]
>>> data.reindex(df.index).values
array([nan, nan, nan, nan], dtype=object)

Encore plus de creusement conduit à l'appel de reindex dans l'attribut index qui donne un résultat étrange :

>>> data.index.reindex(df.index)
(Index([A, B, C, D], dtype=object), array([-1, -1, -1, -1], dtype=int32))

Ces -1 sont ensuite traduits en NaNs.

Titre du bogue mis à jour avec une description plus correcte.

La série reçoit un indice implicite 0, ..., N-1 lorsque vous n'en fournissez pas un - c'est donc exactement le comportement auquel je m'attendrais. Si data était un ndarray brut ou une liste, cela ne se produirait pas. Donc le fait que lorsque vous faites :

df[col] = series

et il conforme la série exactement à l'index de df , c'est une fonctionnalité et pas un bug :) donc

df['test'] = ids.values

fonctionnerait bien dans ton exemple

Dans ce cas, cela devrait peut-être être documenté quelque part si ce n'est déjà fait. En attendant, je vais ajuster mon propre code comme vous l'avez suggéré, merci.

http://pandas.sourceforge.net/dsintro.html#column -selection-addition-deletion

When inserting a Series that does not have the same index as the DataFrame, it will be conformed to the DataFrame’s index:

In [180]: df['one_trunc'] = df['one'][:2]

In [181]: df
Out[181]: 
   one  flag   foo  one_trunc
a  1    False  bar  1        
b  2    False  bar  2        
c  3    True   bar  NaN      
d  NaN  False  bar  NaN      

You can insert raw ndarrays but their length must match the length of the DataFrame’s index.

Quelle est l'idée derrière le fait que lors de l'insertion d'une série qui n'a pas le même index que le DataFrame, elle sera conforme à l'index du DataFrame ?

Lors de la création d'un DataFrame à partir d'une série, l'index résultant couvre tous les index de série individuels. Alors pourquoi cette idée n'est-elle pas utilisée lorsque df['new_column'] = series ?
Vous essayez donc d'ajouter des données, mais ignorez toutes les valeurs qui ne correspondent pas à l'index DataFrame ?
Si _index extension_ existait, on pourrait toujours faire df['new_column'] = series.reindex(df.index) quand on ne veut pas étendre l'index (comportement actuel) ?

In [256]: df = pandas.DataFrame({'A': pandas.Series(['foo', 'bar'], index=['a', 'b']),
   .....:                        'B': pandas.Series([10, 20], index=['b', 'c'])})

In [257]: df
Out[257]:
   A    B
a  foo  NaN
b  bar  10.000
c  NaN  20.000

In [258]: df['C'] = pandas.Series(range(3), index=['a', 'c', 'd'])

In [259]: df
Out[259]:
   A    B       C
a  foo  NaN     0.000
b  bar  10.000  NaN
c  NaN  20.000  1.000

Dans l'exemple ci-dessus, je m'attendrais à une ligne « d » dans le DataFrame.

Eh bien, je pense que l'idée de base est que DataFrame est un "conteneur de série de type dict de longueur fixe". Lorsque vous construisez un DataFrame avec un dict de Series sans index explicite, il n'y a pas d'index évident autre que l'union de tous.

Je peux voir l'argument pour étendre implicitement l'index, mais il y a des compromis de toute façon

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

ebran picture ebran  ·  3Commentaires

Ashutosh-Srivastav picture Ashutosh-Srivastav  ·  3Commentaires

ericdf picture ericdf  ·  3Commentaires

scls19fr picture scls19fr  ·  3Commentaires

matthiasroder picture matthiasroder  ·  3Commentaires