2014-10-17 5 views
1

Не эксперт в Pandas, но я хотел бы знать, есть ли pythonic способ превратить серию в Pandas DF в заголовки столбцов с данными, состоящими из массивов «1s» и "0s".Pandas DF Pivot/Transform/Vectorize Operation

У меня есть следующий DataFrame:

df1 = pd.DataFrame({'x':[254,300,300,300,850,850,1000], 
        'y':[57,12,34,45,8,45,9]}) 

х и у являются векторами одного и того же размера, и я хотел бы «х», чтобы быть индекс и значения в «у», чтобы быть столбцы заголовков, с «0» и «1», представляющее наличие/отсутствие у значений в строке х, так что мой трансформировали DF выглядит более или менее как это:

enter image description here

ответ

3

Использование unstack может быть быстрее:

In [245]: 

df1['z'] = 1 
df1.groupby(['x', 'y']).count().unstack().fillna(0) 
     z      
y  8 9 12 34 45 57 
x       
254 0 0 0 0 0 1 
300 0 0 1 1 1 0 
850 1 0 0 0 1 0 
1000 0 1 0 0 0 0 

In [256]: 

%timeit pd.crosstab(df1['x'], df1['y']) 
100 loops, best of 3: 8.72 ms per loop 
In [261]: 

%%timeit 
df1['z'] = 1 
df1.groupby(['x', 'y']).count().unstack().fillna(0) 
100 loops, best of 3: 4.75 ms per loop 
In [262]: 

%%timeit 
df1['z'] = 1 
df1.groupby(['x', 'y']).sum().unstack().fillna(0) 
100 loops, best of 3: 4.88 ms per loop 
1

Много вариантов, один из которых заключается в использовании функции crosstab, специально предназначенные для этого (docs):

In [2]: pd.crosstab(df1['x'], df1['y']) 
Out[2]: 
y  8 9 12 34 45 57 
x 
254 0 0 0 0 0 1 
300 0 0 1 1 1 0 
850 1 0 0 0 1 0 
1000 0 1 0 0 0 0 
1

Менее вещий и очень интуитивное решение заключается в следующем:

x_set = sorted(set(df1.x.tolist())) 
y_set = sorted(set(df1.y.tolist())) 

dF = pd.DataFrame({}, index=x_set, columns=y_set).fillna(0).sort_index() 
dF.index.name = 'x' 
dF.columns.name = 'y' 
for idx, row in df1.iterrows(): 
    a = row['x'] 
    b = row['y'] 
    dF.loc[a, b] += 1 

Который производит это:

enter image description here