Pandas: Ao adicionar uma série a um DataFrame com um índice diferente, a série se transforma em todos os NaNs

Criado em 6 dez. 2011  ·  9Comentários  ·  Fonte: pandas-dev/pandas

Caso em questão:

>>> 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

Isso também acontece com objetos flutuantes e semelhantes. Não tenho certeza de qual é o gatilho.

Comentários muito úteis

O Series recebe um índice implícito 0, ..., N-1 quando você não fornece um - então este é exatamente o comportamento que eu esperaria. Se data fosse um ndarray bruto ou uma lista, isso não ocorreria. Portanto, o fato de que quando você faz:

df[col] = series

e conforma a série exatamente com o índice de df , que é uma característica e não um bug :) então

df['test'] = ids.values

funcionaria bem no seu exemplo

Todos 9 comentários

Eu me pergunto se isso está relacionado a este problema que também encontrei esta manhã:

>>> 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  

Parece algum tipo de erro aleatório para mim.

Pesquisas adicionais levam à chamada de Series.reindex ao definir itens como sendo o culpado:

>>> 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)

Ainda mais escavações levam a reindex no atributo index sendo chamado, o que dá um resultado estranho:

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

Esses -1 são então traduzidos para NaNs.

Título do bug atualizado com uma descrição mais correta.

O Series recebe um índice implícito 0, ..., N-1 quando você não fornece um - então este é exatamente o comportamento que eu esperaria. Se data fosse um ndarray bruto ou uma lista, isso não ocorreria. Portanto, o fato de que quando você faz:

df[col] = series

e conforma a série exatamente com o índice de df , que é uma característica e não um bug :) então

df['test'] = ids.values

funcionaria bem no seu exemplo

Nesse caso, talvez deva ser documentado em algum lugar, se ainda não estiver. Enquanto isso, ajustarei meu próprio código conforme você sugeriu, obrigado.

http://pandas.sourceforge.net/dsintro.html#column -selection-additional-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.

Qual a ideia por trás do fato de que ao inserir uma Série que não possui o mesmo índice do DataFrame, ela será conformada ao índice do DataFrame?

Ao criar um DataFrame a partir de séries, o índice resultante cobre todos os índices de séries individuais. Então, por que essa ideia não é usada quando df ['new_column'] = series?
Então você tenta adicionar dados, mas ignora todos os valores que não correspondem ao índice DataFrame?
Se _index extension_ existir, pode-se sempre fazer df ['new_column'] = series.reindex (df.index) quando não se deseja estender o índice (comportamento atual)?

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

No exemplo acima, eu esperaria uma linha 'd' no DataFrame.

Bem, eu acho que a ideia básica é que o DataFrame é um "contêiner tipo dict de comprimento fixo de Series". Quando você constrói um DataFrame com um dict de Series sem um índice explícito, não há índice óbvio além da união de todos eles.

Eu posso ver o argumento para estender implicitamente o índice, mas há compensações de qualquer maneira

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

jsexauer picture jsexauer  ·  81Comentários

simonjayhawkins picture simonjayhawkins  ·  53Comentários

rvernica picture rvernica  ·  46Comentários

quicknir picture quicknir  ·  58Comentários

jreback picture jreback  ·  61Comentários