我将从示例开始,然后分解正在发生的事情。
这是一个示例输入:
DataFrame:
**Name** **No.** **Test** ***Grade***
Bob 2123320 Math Nan
Joe 2832883 English 90
John 2139300 Science 85
Bob 2123320 History 93
John 2234903 Math 99
希望输出:
**Name** ********2139300********* ********2234903*******
Math English Science Math English Science
John 0 0 85 99 0 0
就像标题所示,我正在尝试应用多个索引。因此,基本上它首先查找每个名称,然后查找每个名称,以查看它有多少不同的号码。在这种情况下,它设置一个阈值至少2个不同的号码(这就是为什么只输出John而Joe / Bob不输出。)
现在,在这些不同的No中。我有一个我想要搜索的特定测试子集,在这种情况下只有{Math,English,Science}。对于这些测试中的每一个,如果有关人员在该编号中进行测试,则应该有一个等级。我希望该等级被输出用于有关测试,并且对于那个人没有采取的测试,我希望它输出某种简单的标记(即如果那个人当天只拿数学,英语和科学输出0)。
因此,实际上,它首先根据不同的编号对人进行索引,并将它们分组。然后它按Test的类型对它们进行索引(我只想要一个子集)。它最终为每个人分配了他们所采用的测试类型的值,并且他们没有为他们输出一个0。
它类似于我之前提到的另一个问题: Grouped Feature Matrix in Python #2- Follow Up
除了现在而不是1和0之外,我还有另一个列,其中包含我想输出的实际值。
谢谢。
编辑:更多样本/输出
**Name** **No.** **Test** ***Grade***
Bob 2123320 Math Nan
Joe 2832883 English 90
John 2139300 Science 85
Bob 2123320 History 93
John 2234903 Math 99
Bob 2932848 English 99
**Name** 2139300 2234903 2123320 2932848
M E S M E S M E S M E S
John 0 0 85 99 0 0 Nan Nan Nan Nan Nan Nan
Bob Nan Nan Nan Nan nan Nan 86 0 0 0 99 0
答案 0 :(得分:1)
您可以使用pivot_table
:
In [11]: df.pivot_table(values="Grade", index=["Name"], columns=["No.", "Test"])
Out[11]:
No. 2123320 2139300 2234903 2832883
Test History Science Math English
Name
Bob 93.0 NaN NaN NaN
Joe NaN NaN NaN 90.0
John NaN 85.0 99.0 NaN
使用dropna标志包含所有NaN列:
In [12]: df.pivot_table(values="Grade", index=["Name"], columns=["No.", "Test"], dropna=False)
Out[12]:
No. 2123320 2139300 2234903 2832883
Test English History Math Science English History Math Science English History Math Science English History Math Science
Name
Bob NaN 93.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Joe NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 90.0 NaN NaN NaN
John NaN NaN NaN NaN NaN NaN NaN 85.0 NaN NaN 99.0 NaN NaN NaN NaN NaN
并且fill_value = 0
In [13]: df.pivot_table(values="Grade", index=["Name"], columns=["No.", "Test"], dropna=False, fill_value=0)
Out[13]:
No. 2123320 2139300 2234903 2832883
Test English History Math Science English History Math Science English History Math Science English History Math Science
Name
Bob 0 93 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Joe 0 0 0 0 0 0 0 0 0 0 0 0 90 0 0 0
John 0 0 0 0 0 0 0 85 0 0 99 0 0 0 0 0
答案 1 :(得分:1)
让我们使用:
将数据框过滤为仅与您有关的记录
df_out = df[df.groupby(['Name'])['No.'].transform(lambda x: x.nunique() > 1)]
现在,使用set_index
,unstack
和reindex
重塑数据框:
df_out.set_index(['Name','No.','Test'])['Grade'].sum(level=[0,1,2])\
.unstack(-1, fill_value=0)\
.reindex(['Math','English','Science'], axis=1, fill_value=0)\
.unstack(-1, fill_value=0).swaplevel(0, 1, axis=1)\
.sort_index(1)
输出:
No. 2123320 2139300 2234903 2932848
Test English Math Science English Math Science English Math Science English Math Science
Name
Bob 0 0 0 0 0 0 0 0 0 99 0 0
John 0 0 0 0 0 85 0 99 0 0 0 0