给出以下数据框:
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%
提前致谢!
答案 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
不是为President
和Position
设置单独的列,而是有一个名为Position
的列更好,因为Position
是变量,每个观察或行可以包含Contractor
的一个值 - President
或Item 1
。
同样,Item 2
和Item
应合并为一列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
拥有一个列为Position
和In [408]: longref
Out[408]:
Item Position
0 Item 1 Contractor
1 Item 1 President
2 Item 2 President
的DataFrame会更整洁:
melted
以longref
和merged = 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
如何整理longref
以reference
:
只需遍历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
如何整理melted
以pd.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 2
和Item
列合并为一个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}}