Pandas DF Pivot / Transform / Vectorize Operation

时间:2014-10-17 14:20:07

标签: python pandas

不是Pandas的专家,但我想知道是否有一种pythonic方法可以将Pandas DF中的系列转换为列标题,其数据由" 1s"和" 0s"。

我有以下DataFrame:

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

x和y是相同大小的矢量,我希望" x"作为索引和" y"中的值成为列标题,用" 0"和" 1"表示行x中y值的存在/不存在,因此我的变换DF看起来或多或少像这样:

enter image description here

3 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分:1)

这是一个不那么pythonic和非常直观的解决方案:

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