Pandas: Beim Hinzufügen einer Serie zu einem DataFrame mit einem anderen Index wird die Serie in alle NaNs umgewandelt

Erstellt am 6. Dez. 2011  ·  9Kommentare  ·  Quelle: pandas-dev/pandas

Fallbeispiel:

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

Dies geschieht auch bei Float-Objekten und dergleichen. Ich bin mir nicht sicher, was der Auslöser ist.

Hilfreichster Kommentar

Die Serie erhält einen impliziten 0, ..., N-1-Index, wenn Sie keinen angeben. Dies ist also genau das Verhalten, das ich erwarten würde. Wenn data ein rohes Ndarray oder eine Liste wäre, würde dies nicht passieren. Also die Tatsache, dass, wenn Sie Folgendes tun:

df[col] = series

und es entspricht der Serie genau dem Index von df , das ist ein Feature und kein Fehler :) also

df['test'] = ids.values

würde in deinem beispiel gut funktionieren

Alle 9 Kommentare

Ich frage mich, ob es mit diesem Problem zusammenhängt, das ich heute Morgen auch gefunden habe:

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

Sieht für mich nach einer Art Off-by-One-Fehler aus.

Weiteres Graben führt zum Aufruf von Series.reindex wenn Gegenstände als Täter eingestuft werden:

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

Noch mehr Nachforschungen führen dazu, dass reindex im Indexattribut aufgerufen wird, was zu einem seltsamen Ergebnis führt:

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

Diese -1 werden dann in NaNs übersetzt.

Aktualisierter Fehlertitel mit genauerer Beschreibung.

Die Serie erhält einen impliziten 0, ..., N-1-Index, wenn Sie keinen angeben. Dies ist also genau das Verhalten, das ich erwarten würde. Wenn data ein rohes Ndarray oder eine Liste wäre, würde dies nicht passieren. Also die Tatsache, dass, wenn Sie Folgendes tun:

df[col] = series

und es entspricht der Serie genau dem Index von df , das ist ein Feature und kein Fehler :) also

df['test'] = ids.values

würde in deinem beispiel gut funktionieren

In diesem Fall sollte es vielleicht irgendwo dokumentiert werden, falls dies noch nicht geschehen ist. In der Zwischenzeit werde ich meinen eigenen Code anpassen, wie Sie vorgeschlagen haben, danke.

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.

Was ist die Idee hinter der Tatsache, dass beim Einfügen einer Serie, die nicht den gleichen Index wie der DataFrame hat, diese an den Index des DataFrame angepasst wird?

Beim Erstellen eines DataFrame aus Serien deckt der resultierende Index alle einzelnen Serienindizes ab. Warum wird diese Idee also nicht verwendet, wenn df['new_column'] = series?
Sie versuchen also, Daten hinzuzufügen, ignorieren aber alle Werte, die nicht mit dem DataFrame-Index übereinstimmen?
Wenn _index extension_ existieren würde, könnte man immer df['new_column'] = series.reindex(df.index) machen, wenn man den Index nicht erweitern möchte (aktuelles Verhalten)?

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

Im obigen Beispiel würde ich eine Zeile 'd' im DataFrame erwarten.

Nun, ich denke, die Grundidee ist, dass DataFrame ein "Diktier-ähnlicher Container mit fester Länge von Series" ist. Wenn Sie einen DataFrame mit einem Diktat von Series ohne expliziten Index erstellen, gibt es keinen anderen offensichtlichen Index als die Vereinigung aller.

Ich kann das Argument für eine implizite Erweiterung des Index sehen, aber es gibt in beiden Fällen Kompromisse

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

matthiasroder picture matthiasroder  ·  3Kommentare

andreas-thomik picture andreas-thomik  ·  3Kommentare

amelio-vazquez-reina picture amelio-vazquez-reina  ·  3Kommentare

scls19fr picture scls19fr  ·  3Kommentare

venuktan picture venuktan  ·  3Kommentare