2016-04-26 60 views
0

我有一個熊貓系列一個數據幀,其中每個小區是一個字典:灌裝高速

data.individus.head(5) 
Out[25]: 
0 [{'dateDeNaissance': 1954-09-14 00:00:00, 'enc... 
1 [{'dateDeNaissance': 1984-09-14 00:00:00, 'enc... 
2 [{'enceinte': False, 'dateDeNaissance': 1981-0... 
3 [{'dateDeNaissance': 1989-09-14 00:00:00, 'enc... 
4 [{'enceinte': False, 'dateDeNaissance': 1989-0... 
Name: individus, dtype: object 

我想使用每個dictionnary構建大熊貓數據幀,像這樣:

t_individus.ix[:, ['dateDeNaissance', 'enceinte']].head() 
Out[14]: 
     dateDeNaissance enceinte 
0 1954-09-14 00:00:00 False 
1 1984-09-14 00:00:00 False 
2 1981-09-14 00:00:00 False 
3 1989-09-14 00:00:00 False 
4 1989-09-14 00:00:00 False 

請注意,我有更多的鍵(〜50),但我爲例子顯示了2。

我嘗試兩種不同的方式,但我並不完全滿意的處理速度:

1/Concatening

serie = data.foo # 110199 lines 
keys = get_all_possible_keys(serie) # 48 keys (process time: 0.8s) 
table = pd.DataFrame(columns=list(keys)) 

for i in serie: 
    df = pd.DataFrame(list(i.items())) 
    df = df.transpose() 
    df.columns = df.iloc[0] 
    df = df.reindex(df.index.drop(0)) 
    table = pd.concat([table, df], axis=0) 

它啓動速度快,然後緩慢下降,而table變大。整個過程大約需要1個小時。

2 /按行

serie = data.foo 
keys = get_all_possible_keys(serie) 
len_serie = len(serie) 
# -- Pre-allocate memory by declaring size 
table = pd.DataFrame(np.nan, 
        index=range(0, len_serie), 
        columns=list(keys)) 
# -- Fill row by row 
k = 0 
for i in serie: 
    table.loc[k] = pd.Series(i[0]) 
    k += 1 

處理時間取決於table的大小預分配存儲器和填充行。對於一個子集(~10K行),速度要快得多,而對於完整的數據集(11萬行),速度要慢得多。

2個問題:

  1. 爲什麼方法2得到這麼慢時table大(比方法1慢得多),而其僅填充空行?
  2. 關於如何加快流程的任何想法?
+0

也許這裏的問題是,它不知道什麼dtypes是前期當你構建你的數據幀像這樣的方法2,使您的DF將有一個混合dtype直到你完全填充df,如果你知道dtypes你可以嘗試在構造函數中傳遞這些dtypes,並說你看起來不能傳遞混合的dtypes。一種方法是將所有行設置爲與第一個條目相同的值,然後逐行更新 – EdChum

回答

2

這幾乎是相同的思路@詹姆斯的,但在你的情況,你有一系列類型的字典的名單,你要轉換的類型的字典的列表或一系列的類型的字典第一:

In [12]: s 
Out[12]: 
0 [{'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}] 
1  [{'a': 'a1', 'b': 'b1', 'c': 'c1'}] 
dtype: object 

In [13]: pd.DataFrame(s.sum()) 
Out[13]: 
    a b c 
0 aaa bbb ccc 
1 a1 b1 c1 

In [14]: s.sum() 
Out[14]: [{'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}, {'a': 'a1', 'b': 'b1', 'c': 'c1'}] 

使用.tolist()

In [15]: pd.DataFrame(s.tolist()) 
Out[15]: 
             0 
0 {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'} 
1  {'a': 'a1', 'b': 'b1', 'c': 'c1'} 
3

我發現在過去,從一系列的字典中構建一個數據框是非常快的。我簡單的建議是嘗試,

dataframe = pandas.DataFrame(data.foo.tolist()) 
+0

我認爲在這種情況下它應該是'pd.DataFrame(data.individus.sum())' – MaxU