给出示例df
:
df = pd.DataFrame([['William', 1, 0, 'T', 0, 1],['James', 0, 1, 'R', 1, 1],['James', 1, 0, 'S', 0, 1],['Dean', 1, 0, 'R', 1, 0],['William', 0, 1, 'S', 0, 0],['James', 0, 0, 'S', 0, 1]],columns=['Name','x1','x2','x3','x4','x5'])
Name x1 x2 x3 x4 x5
0 William 1 0 T 0 1
1 James 0 1 R 1 1
2 James 1 0 S 0 1
3 Dean 1 0 R 1 0
4 William 0 1 S 0 0
5 James 0 0 S 0 1
之前我曾问过一个问题,如何将各种过滤器应用于此df
并输出从groupby
应用于每个组对象的一系列函数的结果,于是我得出了以下解决方案:
variables = {'x1': 'sum','x2': 'sum','x4': 'sum','x5': 'sum'}
filters = {'Option1': df['x3']=='S', 'Option2': df['x3']=='R', 'Option3': (df['x2']==1) | (df['x4']==1) | (df['x5']==1), 'Option4': df['x2']==1, 'Option5': df['x2']==0, 'Option6': df['x5']==1}
out = {key: df[f].groupby('Name').agg(variables) for key, f in filters.items()}
out = pd.concat(results)
连接结果后,剩下以下内容:
x1 x2 x4 x5
Name
Option1 James 1 0 0 2
William 0 1 0 0
Option2 Dean 1 0 1 0
James 0 1 1 1
Option3 Dean 1 0 1 0
James 1 1 1 3
William 1 1 0 1
Option4 James 0 1 1 1
William 0 1 0 0
Option5 Dean 1 0 1 0
James 1 0 0 2
William 1 0 0 1
Option6 James 1 1 1 3
William 1 0 0 1
我想再次groupby('Name')
,这给了我
x1 x2 x4 x5
Name
Option2 Dean 1 0 1 0
Option3 Dean 1 0 1 0
Option5 Dean 1 0 1 0
x1 x2 x4 x5
Name
Option1 James 1 0 0 2
Option2 James 0 1 1 1
Option3 James 1 1 1 3
Option4 James 0 1 1 1
Option5 James 1 0 0 2
Option6 James 1 1 1 3
x1 x2 x4 x5
Name
Option1 William 0 1 0 0
Option3 William 1 1 0 1
Option4 William 0 1 0 0
Option5 William 1 0 0 1
Option6 William 1 0 0 1
但是,我有一些列(或行,具体取决于您如何看待它们)从结果中排除(例如,过滤器df['x3']=='S'
将使Name
列中没有{ {1}})。我觉得我真的很靠近这里,但这是我想要的输出(名称的排序不相关):
'Dean'
谢谢您的指导。
答案 0 :(得分:4)
您可以通过重新索引out
DataFrame并交换索引级别来完成所需的操作。从连接的结果开始:
from itertools import product
# Swap the index levels
out = out.swaplevel(0,1)
# Form the product of the two index levels
ids = list(product(out.index.get_level_values(0).unique(),
out.index.get_level_values(1).unique()))
# Reindex out, filling missing with 0 and sorting the index
out = out.reindex(ids).fillna(0).sort_index().astype('int')
out
现在是:
x1 x2 x4 x5
Name
Dean Option1 0 0 0 0
Option2 1 0 1 0
Option3 1 0 1 0
Option4 0 0 0 0
Option5 1 0 1 0
Option6 0 0 0 0
James Option1 1 0 0 2
Option2 0 1 1 1
Option3 1 1 1 3
Option4 0 1 1 1
Option5 1 0 0 2
Option6 1 1 1 3
William Option1 0 1 0 0
Option2 0 0 0 0
Option3 1 1 0 1
Option4 0 1 0 0
Option5 1 0 0 1
Option6 1 0 0 1