熊猫数据透视表与花式堆叠

时间:2016-05-16 01:04:44

标签: python-3.x pandas pivot-table

给出以下数据框:

results = pd.DataFrame({'Contractor':[1,1,0,0,0,1],
                    'President':[1,0,0,0,1,1],
                   'Item 1':[1,1,0,0,1,np.nan],
                   'Item 2':[1,0,0,1,0,1]})
results[['Contractor','President','Item 1','Item 2']]

results

    Contractor  President   Item 1  Item 2
0        1          1       1       1
1        1          0       1       0
2        0          0       0       0
3        0          0       0       1
4        0          1       1       0
5        1          1       NaN     1

这是为了参考项目(见下文):

    Position    Item(s)
0   Contractor  1
1   President   1,2

...我想转动数据来产生这个:

    Position    Overall%
0   Contractor  100
1   President   80

......基于这个逻辑:

因为总统关注的是第1项和第2项,所以需要考虑5个数字:第1项中的(1和1)以及项目2中的(1,0和1)。项目之间的总和< / strong>为4,项目的计数为5(不计算'NaN'),这为80%。

因为承包商只关注第1项,所以需要考虑2个数字:1和1 - 'NaN'不应计算 - (分别来自感兴趣的行)。因此,总和是计数中的2,即2,这给出了100%

提前致谢!

1 个答案:

答案 0 :(得分:2)

     Position  Overall%
0  Contractor     100.0
1   President      80.0

产量

results

解释Hadley Wickham有一篇文章 (PDF)提出了这些优点 制作数据&#34; tidy&#34;。主要原则是每行应该 代表&#34;观察&#34;每列代表一些因素或变量。

经常会发现您需要用来表达计算的工具 一旦数据整洁,它将很自然地落到位。 这个问题的难度很大程度上来自数据不整齐。

考虑In [405]: results Out[405]: Contractor Item 1 Item 2 President 0 1 1.0 1 1 1 1 1.0 0 0 2 0 0.0 0 0 3 0 0.0 1 0 4 0 1.0 0 1 5 1 NaN 1 1

Contractor

不是为PresidentPosition设置单独的列,而是有一个名为Position的列更好,因为Position是变量,每个观察或行可以包含Contractor的一个值 - PresidentItem 1。 同样,Item 2Item应合并为一列In [416]: melted Out[416]: Position Item value 0 Contractor Item 1 1.0 1 Contractor Item 1 1.0 2 Contractor Item 1 NaN 3 President Item 1 1.0 4 President Item 1 1.0 5 President Item 1 NaN 6 Contractor Item 2 1.0 7 Contractor Item 2 0.0 8 Contractor Item 2 1.0 9 President Item 2 1.0 10 President Item 2 0.0 11 President Item 2 1.0

melted

results包含与value相同的信息,但格式整齐。 results[['Item 1', 'Item 2']]列包含results['Contractor']中的值。每行对应一个&#34;观察&#34;其中In [407]: reference Out[407]: Item(s) Position 0 (1,) Contractor 1 (1, 2) President 或结果[&#39;总统&#39;]等于1,因为计算的逻辑只需要这些值。

同样,而不是

Item

拥有一个列为PositionIn [408]: longref Out[408]: Item Position 0 Item 1 Contractor 1 Item 1 President 2 Item 2 President 的DataFrame会更整洁:

melted

longrefmerged = pd.merge(longref, melted, how='left') # Item Position value # 0 Item 1 Contractor 1.0 # 1 Item 1 Contractor 1.0 # 2 Item 1 Contractor NaN # 3 Item 1 President 1.0 # 4 Item 1 President 1.0 # 5 Item 1 President NaN # 6 Item 2 President 1.0 # 7 Item 2 President 0.0 # 8 Item 2 President 1.0 grouped = merged.groupby(['Position']) result = (grouped['value'].sum() / grouped['value'].count())*100 result = result.rename('Overall%').reset_index() 的形式获得整洁的数据版本后, 计算所需的结果非常简单:

reference

如何整理longrefreference

只需遍历longref行,并为每一行迭代项目元组以构建新的DataFrame,longref = pd.DataFrame([('Item {}'.format(item), row['Position']) for index, row in reference.iterrows() for item in row['Item(s)']], columns=['Item', 'Position'])

results

如何整理meltedpd.melt

可以通过两次调用pd.melt来完成。 melted = pd.melt(results, id_vars=['Item 1','Item 2'], var_name='Position') # we only care about rows where Contractor or President value was 1. So use .loc to select those rows. melted = melted.loc[melted['value']==1] # Item 1 Item 2 Position value # 0 1.0 1 Contractor 1 # 1 1.0 0 Contractor 1 # 5 NaN 1 Contractor 1 # 6 1.0 1 President 1 # 10 1.0 0 President 1 # 11 NaN 1 President 1 转换&#34;广泛&#34;格式为&#34;长&#34;格式化DataFrames。它可以将多个列合并为一个列。例如,要将Contractor和President列合并到一个Position列中,您可以使用:

Item 1

同样,要将Item 2Item列合并为一个melted = pd.melt(melted, id_vars=['Position'], value_vars=['Item 1','Item 2'], var_name='Item') # Position Item value # 0 Contractor Item 1 1.0 # 1 Contractor Item 1 1.0 # 2 Contractor Item 1 NaN # 3 President Item 1 1.0 # 4 President Item 1 1.0 # 5 President Item 1 NaN # 6 Contractor Item 2 1.0 # 7 Contractor Item 2 0.0 # 8 Contractor Item 2 1.0 # 9 President Item 2 1.0 # 10 President Item 2 0.0 # 11 President Item 2 1.0 列,请使用:

{{1}}