2017-07-03 4 views
0

Ich habe eine Liste, die, wenn ausgefüllt, wird in eine pandas dataframe gelegt werden. Manchmal hat die 4 Elemente in jedem list, manchmal hat es 3.Pandas behaupten Fehler für leere Spalte

# Example list 1 
[["foo1", "baa1", "faa1", "gaa1"], ["foo2", "baa2", "faa2", "gaa2"], ["foo3", "baa3", "faa3", "gaa3"]] 

# Example list 2 
[["foo1", "baa1", "faa1"], ["foo2", "baa2", "faa2"], ["foo3", "baa3", "faa3", "gaa3"]] 

definiere ich meine Pandas Datenrahmen Spalten, wenn ich die main_list hineinlesen. Ich habe anscheinend kein Problem, den folgenden Code für example list 1 and 2 auszuführen.

pandas.Dataframe(example_list, columns={"col1", "col2", "col3", "col4"}) 

Mein Problem kommt, wenn manchmal, zu besonderen Anlässen, example list 3 kommt

# Example list 3 
[["foo1", "baa1", "faa1"], ["foo2", "baa2", "faa2"], ["foo3", "baa3", "faa3"]] 

Wenn dies geschieht, gibt es nur 3 Elemente in der Liste statt der üblichen 4. Pandas werden mir dann eine AssertionError: 4 columns passed, passed data had 3 columns

Ich verstehe, was passiert, dass, weil es nur 3 Elemente gibt. Aber was kann ich tun, um dieses Problem zu lösen?

Antwort

1

Sie zunächst ein generisches Datenrahmen schaffen könnte (ohne Angabe der Spaltennamen) und benennen Sie anschließend die Spalten nach dem Datum um:

Wenn example_list Ihr drittes Beispiel ist, wird pd.DataFrame(example_list) nur 3 Spalten haben. Um sicherzustellen, dass df alle vier Spalten enthält, verwenden Sie reindex. Dies ist der Zweck der letzten Zeile oben.


Zum Beispiel

import pandas as pd 

A = [["foo1", "baa1", "faa1", "gaa1"], ["foo2", "baa2", "faa2", "gaa2"], ["foo3", "baa3", "faa3", "gaa3"]] 

B = [["foo1", "baa1", "faa1"], ["foo2", "baa2", "faa2"], ["foo3", "baa3", "faa3", "gaa3"]] 

C = [["foo1", "baa1", "faa1"], ["foo2", "baa2", "faa2"], ["foo3", "baa3", "faa3"]] 

columns = "col1", "col2", "col3", "col4" 

for example_list in (A, B, C): 
    df = pd.DataFrame(example_list) 
    df.columns = columns[:len(df.columns)] 
    df = df.reindex(columns=columns) 
    print(df) 

ergibt

col1 col2 col3 col4 
0 foo1 baa1 faa1 gaa1 
1 foo2 baa2 faa2 gaa2 
2 foo3 baa3 faa3 gaa3 
    col1 col2 col3 col4 
0 foo1 baa1 faa1 None 
1 foo2 baa2 faa2 None 
2 foo3 baa3 faa3 gaa3 
    col1 col2 col3 col4 
0 foo1 baa1 faa1 NaN 
1 foo2 baa2 faa2 NaN 
2 foo3 baa3 faa3 NaN 
2

Dies ist, was ich eine generische Lösung haben, tun würde, mit Pandas reindex:

column_names = ["col1", "col2", "col3", "col4"] 

def max_elements(nested_lst): 
    return max([len(lst) for lst in nested_lst])  

pandas.DataFrame(example_list, 
       columns=column_names[:max_elements(example_list)]).reindex(columns = column_names) 

Dies ist meine Ausgabe mit Ihrer neuesten Liste:

col1 col2 col3 col4 
0 foo1 baa1 faa1 NaN 
1 foo2 baa2 faa2 NaN 
2 foo3 baa3 faa3 NaN 
+0

Hmm, wäre es anstelle der leeren Spalte tun möglich sein, so etwas wie 'fillna' für? –

+0

Sicher, mit welchem ​​Wert möchten Sie die Spalte füllen? Sie können das fill_value Argument von Reindex verwenden – FLab

+0

Nein, ich meine wie, behalten Sie diese "4 column_names", aber füllen Sie die leere Spalte mit NAN oder etwas. Wird das möglich sein? Ich bin geneigt, '4 column_names' zu behalten, weil die Codes später davon Gebrauch machen. –