2017-06-13 54 views
4

我有一個包含各個樣本的各個區域的依次列表。我想製作一個數據框,以便每行(樣本)都存在或不存在相應的區域(列)。例如,數據可能是這樣的:Python:使用基於獨立值的列創建大熊貓數據框,位於依賴列表中

region_list = [['North America'], ['North America', 'South America'], ['Asia'], ['North America', 'Asia', 'Australia']] 

和最終數據框會是這個樣子:

North America South America  Asia  Australia 
1    0     0  0 
1    1     0  0 
0    0     1  0 
1    0     1  1 

我想我可以使用依偎循環可能想出一個辦法,並附加,但是否有更pythonic的方式來做到這一點?也許用numpy.where

回答

6

pandas
str.get_dummies

pd.Series(region_list).str.join('|').str.get_dummies() 

    Asia Australia North America South America 
0  0   0    1    0 
1  0   0    1    1 
2  1   0    0    0 
3  1   1    1    0 

numpy
np.bincountpd.factorize

n = len(region_list) 
i = np.arange(n).repeat([len(x) for x in region_list]) 
f, u = pd.factorize(np.concatenate(region_list)) 
m = u.size 

pd.DataFrame(
    np.bincount(i * m + f, minlength=n * m).reshape(n, m), 
    columns=u 
) 

    North America South America Asia Australia 
0    1    0  0   0 
1    1    1  0   0 
2    0    0  1   0 
3    1    0  1   1 

定時

%timeit pd.Series(region_list).str.join('|').str.get_dummies() 
1000 loops, best of 3: 1.42 ms per loop 

%%timeit 
n = len(region_list) 
i = np.arange(n).repeat([len(x) for x in region_list]) 
f, u = pd.factorize(np.concatenate(region_list)) 
m = u.size 

pd.DataFrame(
    np.bincount(i * m + f, minlength=n * m).reshape(n, m), 
    columns=u 
) 
1000 loops, best of 3: 204 µs per loop 
+2

還有另一個piRSquared技巧,我將不得不記住。 「.str.get_dummies的默認值爲'|'。」 +1 –

+1

這真的很棒。不知道有甚麼'get_dummies()'爲'str' –

+0

感謝您的友好的話:-) – piRSquared

1

這將完成這項工作!

import pandas as pd 
import itertools 
pd.get_dummies(pd.DataFrame(list(itertools.chain(*region_list))) 

Output 
     0_Asia 0_Australia 0_North America 0_South America 
    0  0   0    1    0 
    1  0   0    1    0 
    2  0   0    0    1 
    3  1   0    0    0 
    4  0   0    1    0 
    5  1   0    0    0 
    6  0   1    0    0 
+0

你這裏有兩個'_Asia'列,需要加以鞏固。 –

+0

好點,剛修好! –

1

您可以使用chain.from_iterableitertools模塊和list comprehension

from itertools import chain 

region_list = [['North America'], ['North America', 'South America'], ['Asia'], ['North America', 'Asia', 'Australia']] 

regions = list(set(chain.from_iterable(region_list))) 
vals = [[1 if j in k else 0 for j in regions] for k in region_list] 
df = pd.DataFrame(vals, columns=regions) 
print(df) 

輸出:

Australia Asia North America South America 
0   0  0    1    0 
1   0  0    1    1 
2   0  1    0    0 
3   1  1    1    0 
4

讓我們嘗試:

df = pd.DataFrame(region_list) 

df2 = df.stack().reset_index(name='region') 

df_out = pd.get_dummies(df2.set_index('level_0')['region']).groupby(level=0).sum().rename_axis(None) 

print(df_out) 

輸出:

  Asia Australia North America South America            
0   0   0    1    0 
1   0   0    1    1 
2   1   0    0    0 
3   1   1    1    0 
相關問題