2016-04-06 9 views
7

Ich versuche, einen leeren Datenrahmen mit einem Index zu erstellen und die Spaltentypen anzugeben. So wie ich es tue, ist die folgende:Create Empty Dataframe in Pandas mit Angabe von Spaltentypen

df = pd.DataFrame(index=['pbp'],columns=['contract', 
             'state_and_county_code', 
             'state', 
             'county', 
             'starting_membership', 
             'starting_raw_raf', 
             'enrollment_trend', 
             'projected_membership', 
             'projected_raf'], 
           dtype=['str', 'str', 'str', 'str', 'int', 'float', 'float', 'int', 'float']) 

Allerdings habe ich die folgende Fehlermeldung erhalten,

TypeError: data type not understood 

Was bedeutet das?

+0

I don Ich denke, Sie können die dtypes auf diese Weise spezifizieren, Sie können einen einzelnen Typ wie str übergeben, aber keine Liste von Strings. Der dtype wird abgeleitet, wenn Sie die Spaltenwerte zuweisen. Ich denke, dass es unnötig sein sollte um überhaupt – EdChum

+0

@EdChum zu spezifizieren, das stimmt gemäß den [Docs] überein (https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html), frage ich mich jedoch, warum ist das der Konstruktor erlaubt das nicht ... wäre es nicht effizienter, einen leeren Datenrahmen mit den Typen von Anfang an für allocati zu erstellen zu Zwecken? – jimijazz

Antwort

2

Pandas bietet keine reine Integer-Spalte. Sie können entweder die Float-Spalte verwenden und diese Spalte nach Bedarf in eine ganze Zahl umwandeln oder sie wie ein Objekt behandeln. Was Sie versuchen zu implementieren, ist nicht die Art, wie Pandas verwendet werden sollen. Aber wenn Sie das wirklich WIRKLICH wollen, können Sie die TypeError-Nachricht umgehen, indem Sie dies tun.

df1 = pd.DataFrame(index=['pbp'], columns=['str1','str2','str2'], dtype=str) 
df2 = pd.DataFrame(index=['pbp'], columns=['int1','int2'], dtype=int) 
df3 = pd.DataFrame(index=['pbp'], columns=['flt1','flt2'], dtype=float) 
df = pd.concat([df1, df2, df3], axis=1) 

    str1 str2 str2 int1 int2 flt1 flt2 
pbp NaN NaN NaN NaN NaN NaN NaN 

Sie können die Spaltenreihenfolge nach Belieben neu anordnen. Aber das ist nicht die Art und Weise wie Pandas benutzt werden sollten.

df.dtypes 
str1  object 
str2  object 
str2  object 
int1  object 
int2  object 
flt1 float64 
flt2 float64 
dtype: object 

Beachten Sie, dass Int als Objekt behandelt wird.

+1

Wovon zum Teufel redest du? Natürlich unterstützt Pandas ganzzahlige Spalten. – user2357112

+0

Es scheint jedoch ein Problem mit der Übergabe von 'dtype = int' mit keinen Daten zu geben. – user2357112

+0

Das sieht absolut wie ein Fehler aus - ist immer noch das Verhalten in der neuesten Version. Hast du es eingereicht? – user48956

3

Hun hat bereits geantwortet, es ist unmöglich. Also nur eine Bemerkung.

Sie können rund um den Typ Fehler erhalten np.dtype mit:

pd.DataFrame(index = ['pbp'], columns = ['a','b'], dtype = np.dtype([('str','float')])) 

aber Sie bekommen stattdessen:

NotImplementedError: compound dtypes are not implementedin the DataFrame constructor 
+0

Das ist wirklich die richtige Antwort. Selbst wenn man den TypeError repariert, ist es immer noch etwas, was Pandas nicht umsetzen wollten. Sie können nicht einmal einen dtype aus einem bestehenden DataFrame mit zusammengesetzten Datentypen kopieren, um einen neuen leeren DataFrame zu starten, der wirklich wie ein gültiger Anwendungsfall aussieht. –

1

ich diese Frage nach dem Laufen in der gleichen Ausgabe gefunden. Ich bevorzuge die folgende Lösung (Python 3) zum Erstellen eines leeren DataFrame mit kein Index.

import numpy as np 
import pandas as pd 

def make_empty_typed_df(dtype): 
    tdict = np.typeDict 
    types = tuple(tdict.get(t, t) for (_, t, *__) in dtype) 
    if any(t == np.void for t in types): 
     raise NotImplementedError('Not Implemented for columns of type "void"') 
    return pd.DataFrame.from_records(np.array([tuple(t() for t in types)], dtype=dtype)).iloc[:0, :] 

Testing this out ...

from itertools import chain 

dtype = [('col%d' % i, t) for i, t in enumerate(chain(np.typeDict, set(np.typeDict.values())))] 
dtype = [(c, t) for (c, t) in dtype if (np.typeDict.get(t, t) != np.void) and not isinstance(t, int)] 

print(make_empty_typed_df(dtype)) 

Out:

Empty DataFrame 

Columns: [col0, col6, col16, col23, col24, col25, col26, col27, col29, col30, col31, col32, col33, col34, col35, col36, col37, col38, col39, col40, col41, col42, col43, col44, col45, col46, col47, col48, col49, col50, col51, col52, col53, col54, col55, col56, col57, col58, col60, col61, col62, col63, col64, col65, col66, col67, col68, col69, col70, col71, col72, col73, col74, col75, col76, col77, col78, col79, col80, col81, col82, col83, col84, col85, col86, col87, col88, col89, col90, col91, col92, col93, col95, col96, col97, col98, col99, col100, col101, col102, col103, col104, col105, col106, col107, col108, col109, col110, col111, col112, col113, col114, col115, col117, col119, col120, col121, col122, col123, col124, ...] 
Index: [] 

[0 rows x 146 columns] 

und die Datentypen ...

print(make_empty_typed_df(dtype).dtypes) 

O ut:

col0  timedelta64[ns] 
col6    uint16 
col16    uint64 
col23    int8 
col24  timedelta64[ns] 
col25    bool 
col26   complex64 
col27    int64 
col29    float64 
col30    int8 
col31    float16 
col32    uint64 
col33    uint8 
col34    object 
col35   complex128 
col36    int64 
col37    int16 
col38    int32 
col39    int32 
col40    float16 
col41    object 
col42    uint64 
col43    object 
col44    int16 
col45    object 
col46    int64 
col47    int16 
col48    uint32 
col49    object 
col50    uint64 
       ...  
col144    int32 
col145    bool 
col146   float64 
col147  datetime64[ns] 
col148    object 
col149    object 
col150   complex128 
col151 timedelta64[ns] 
col152    int32 
col153    uint8 
col154   float64 
col156    int64 
col157    uint32 
col158    object 
col159    int8 
col160    int32 
col161    uint64 
col162    int16 
col163    uint32 
col164    object 
col165  datetime64[ns] 
col166   float32 
col167    bool 
col168   float64 
col169   complex128 
col170   float16 
col171    object 
col172    uint16 
col173   complex64 
col174   complex128 
dtype: object 

einen Index Hinzufügen wird schwierig, weil es keine echte fehlenden Wert für die meisten Datentypen ist, so dass sie mit einer nativen fehlenden Wert (zB auf eine andere Art am Ende werfen immer int s gegossen zu float s oder object s), aber wenn Sie vollständige Daten der Typen haben, die Sie angegeben haben, können Sie Zeilen nach Bedarf immer einfügen, und Ihre Typen werden respektiert.

df.loc[index, :] = new_row 

Wieder, wie @Hun wies darauf hin, das ist nicht, wie Pandas verwendet werden soll: Dies kann mit erreicht werden.

0

Sie können dies tun, indem Sie ein Wörterbuch in den Datenrahmen Konstruktor:

df = pd.DataFrame(index=['pbp'], 
        data={'contract' : np.full(1, "", dtype=str), 
         'starting_membership' : np.full(1, np.nan, dtype=float), 
         'projected_membership' : np.full(1, np.nan, dtype=int) 
         } 
       ) 

Dies wird richtig geben Ihnen einen Datenrahmen, die wie folgt aussieht:

 contract projected_membership starting_membership 
pbp  ""    NaN   -9223372036854775808 

Mit dtypes:

contract     object 
projected_membership float64 
starting_membership  int64 

Das heißt, es gibt zwei Dinge zu beachten:

1) str ist eigentlich kein Typ, den eine DataFrame-Spalte verarbeiten kann; stattdessen fällt es auf den allgemeinen Fall object zurück. Es wird immer noch richtig funktionieren.

2) Warum sehen Sie nicht NaN unter starting_membership? Nun, NaN ist nur für Floats definiert; Es gibt keinen "None" -Wert für Ganzzahlen, daher wird np.NaN in eine ganze Zahl umgewandelt. Wenn Sie einen anderen Standardwert wünschen, können Sie dies unter np.full ändern.

+0

Keine Notwendigkeit, eine Reihe von Dummy-Daten in die Spalten zu setzen, wenn Sie leere Arrays verwenden konnten. – user2357112

1

Das riecht wirklich wie ein Käfer.

Hier ist eine andere (einfachere) Lösung.

def df_empty(columns, dtypes, index=None): 
    df = pd.DataFrame(index=index) 
    for c,d in zip(columns, dtypes): 
     df[c] = pd.Series(dtype=d) 
    return df 

df = df_empty ([ 'a', 'b'], dtypes = [np.int64, np.int64,] Druckliste (df.dtypes) # int64, int64