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.
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
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 :) doncdf['test'] = ids.values
fonctionnerait bien dans ton exemple