如果在excel中使用Pandas满足条件,则按行添加数据

ovfsdjhp  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(114)

我有一个数据集与标题['Q 36 Marks','Q 37 Marks', ..., 'Q 50 Marks']在数据框从excel文件。数据包含为0.0,-1.0或4.0。和数据是学生出现在考试。我想创建一个新的变量-分数将添加前10个问号为每个学生是4.0或-1.0。我不能用Pandas做它。
例如如果数据

Q 36 Marks Q 37 Marks ... Q 50 Marks (in all 15 questions) and for student the data is 
4          4      -1  0 0 -1 -1 4 -1 4 0 0 -1 -1 4

因此,分数应计算为4+4+(-1)+(-1)+(-1)+4+(-1)+4+(-1)+(-1),不考虑最后4个。
我试着找到Pandas函数.sum(axis=1),但不知道如何找到条件,以获得只有前10个非零条目到总和函数。

au9on6nz

au9on6nz1#

您可以对屏蔽值执行stack以删除不需要的数据,然后仅对前10个值执行groupby.sum

cols = ['Q 36 Marks','Q 37 Marks', 'Q 50 Marks']
df['Score'] = (df[cols] # only required if you want to filter some columns
   .where(df.ne(0)).stack()
   .groupby(level=0).agg(lambda g: g.head(10).sum())
)

输出(仅分数列):

0    10.0
dtype: float64
yfjy0ee7

yfjy0ee72#

使用DataFrame.isin仅测试筛选列中的-1, 4值,通过DataFrame.cumsum测试获得第一个10,将不匹配值设置为DataFrame.where中的0,并将每行的最后一个求和:

cols = ['Q 36 Marks', 'Q 37 Marks', ..., 'Q 50 Marks']

df['Score'] = df[cols].where(df[cols].isin([-1,4]).cumsum(axis=1).le(10), 0).sum(axis=1)

如果需要处理所有列:

#here chain mask is not necessary, because sum of 0 is 0
df['Score'] = df.where(df.isin([-1,4]).cumsum(axis=1).le(10), 0).sum(axis=1)

如果需要更改条件,例如,仅-1值的求和解决方案发生更改:

m = df.eq(-1)
df['Score'] = df.where(m.cumsum(axis=1).le(10) & m, 0).sum(axis=1)

性能测试,此处为1500行:

np.random.seed(123)

df = pd.DataFrame(np.random.choice([-1,0,4], size=(1500, 15)))
df.columns=[f'Q {x+36} Marks' for x in df.columns]

In [153]: %timeit df['Score'] = df.where(df.isin([-1,4]).cumsum(axis=1).le(10), 0).sum(axis=1)
4.76 ms ± 699 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

#mozway solution
In [154]: %timeit df['Score'] = df.where(df.ne(0)).stack().groupby(level=0).agg(lambda g: g.head(10).sum())
319 ms ± 5.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

相关问题