Pandas: При добавлении серии в DataFrame с другим индексом серия превращается во все NaN

Созданный на 6 дек. 2011  ·  9Комментарии  ·  Источник: pandas-dev/pandas

Дело в точке:

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

Это также происходит с объектами типа float и т.п. Я не уверен, что это за спусковой крючок.

Самый полезный комментарий

Серии присваивается неявный индекс 0, ..., N-1, когда вы его не указываете - так что это именно то поведение, которого я ожидал. Если бы data был необработанным массивом ndarray или списком, этого бы не произошло. Так что, когда вы это делаете:

df[col] = series

и он соответствует серии в точности с индексом df , это особенность, а не ошибка :) поэтому

df['test'] = ids.values

будет нормально работать в вашем примере

Все 9 Комментарий

Интересно, связано ли это с этой проблемой, которую я обнаружил сегодня утром:

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

Мне кажется, что это какая-то постепенная ошибка.

Дальнейшее копание приводит к вызову Series.reindex при установке элементов как виновника:

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

Еще больше копаний приводит к reindex в вызываемом атрибуте index, что дает странный результат:

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

Затем эти -1 переводятся в NaN.

Обновлен заголовок ошибки с более правильным описанием.

Серии присваивается неявный индекс 0, ..., N-1, когда вы его не указываете - так что это именно то поведение, которого я ожидал. Если бы data был необработанным массивом ndarray или списком, этого бы не произошло. Так что, когда вы это делаете:

df[col] = series

и он соответствует серии в точности с индексом df , это особенность, а не ошибка :) поэтому

df['test'] = ids.values

будет нормально работать в вашем примере

В этом случае, возможно, это следует где-то задокументировать, если это еще не сделано. А пока я скорректирую свой собственный код, как вы предложили, спасибо.

http://pandas.sourceforge.net/dsintro.html#column -selection-добавление-удаление

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.

В чем заключается идея того факта, что при вставке серии, у которой нет того же индекса, что и у DataFrame, она будет соответствовать индексу DataFrame?

При создании DataFrame из серии результирующий индекс охватывает все индексы отдельных серий. Так почему же эта идея не используется, когда df ['new_column'] = series?
Итак, вы пытаетесь добавить данные, но игнорируете все значения, которые не соответствуют индексу DataFrame?
Если бы _index extension_ существовал, всегда можно было бы сделать df ['new_column'] = series.reindex (df.index), если не хотите расширять индекс (текущее поведение)?

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

В приведенном выше примере я ожидал бы строку «d» в DataFrame.

Что ж, я думаю, основная идея состоит в том, что DataFrame является «контейнером серии фиксированной длины, подобным dict». Когда вы создаете DataFrame с помощью словаря Series без явного индекса, не существует очевидного индекса, кроме их объединения всех.

Я вижу аргумент в пользу неявного расширения индекса, но в любом случае есть компромиссы

Была ли эта страница полезной?
0 / 5 - 0 рейтинги