假设我有一个示例 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
现在,我想通过 Name
对数据帧进行分组,所以:
grouped = df.groupby('Name')
我想迭代一个变量列表并对每个组执行一些计算,使用每个变量作为列名并在传递的组上应用特定的过滤器,例如:
def my_function(x, i):
stats = [x[i].sum(),
x[x['x3']=='L'][i].sum(),
x[x['x3']=='R'][i].sum(),
x[(x['x2']==1) | (x['x4']==1) | (x['x5']==1)][i].sum(),
x[x['x2']==1][i].sum(),
x[x['x2']==0][i].sum(),
x[x['x5']==1][i].sum()]
return pd.Series(stats)
for i in ['x1','x2','x4','x5']:
out = grouped.apply(lambda x: my_function(x, i))
对于小样本数据帧而言,这似乎表现得很快,但对于具有~5000列,~50行和~20个唯一名称的数据帧,这可能需要很长时间才能完成 . 我知道有可能对这种方法进行矢量化或优化 .
有没有办法对上面的过程进行矢量化,知道我需要以相同的方式为外部循环中的每个变量过滤数据?
任何指导将不胜感激 .
EDIT (following Wen's comment):
我将我的变量和条件过滤器放在原始 df
上执行到单独的列表中,然后对生成的过滤数据帧执行 groupby()
,并为每个变量计算相应的 sum()
.
variables = ['x1','x2','x4','x5']
filters = [df['x3']=='S', df['x3']=='R', (df['x2']==1) | (df['x4']==1) | (df['x5']==1), df['x2']==1, df['x2']==0, df['x5']==1]
out = [df[i].groupby('Name')[j].sum() for i in filters for j in variables]
我想我只需要将输出 concat
输入到单个输出数据帧中,但是这会为没有返回总和的情况插入缺失值吗?例如,对于 df['x3']=='S'
, 'Dean'
不会返回0,有没有办法这样做?