获取其中 n 个错误答案的 m 个值的行。

5

我有一个像这样的数据框:

right_answer   rater1   rater2   rater3   item
1              1        1        2        S01
1              1        2        2        S02
2              1        2        1        S03
2              2        1        2        S04

我需要获取“items”中至少有两个三个评分人给出错误答案的行或值。使用以下代码,我已经可以检查所有评分者是否互相一致:

df.where(df[['rater1', 'rater2', 'rater3']].eq(df.iloc[:, 0], axis=0).all(1) == True)

我不想使用多数投票计算一列数据,因为可能需要调整达成一致或不一致的评定者数量。

谢谢帮忙。

2个回答

4
使用 DataFrame.filter 来过滤包含列名为 rater 的数据框,然后在 axis=0 上使用 DataFrame.ne 比较包含 rater 的列与列 right_answer,接着在 axis=1 上使用 DataFrame.sum 获取给出错误答案的 raters 数量,使用 Series.ge 创建一个布尔掩码,最后使用该 mask 过滤数据框行。
mask = (
    df.filter(like='rater')
    .ne(df['right_answer'], axis=0).sum(axis=1).ge(2)
)

df = df[mask]

结果:

# print(df)

   right_answer  rater1  rater2  rater3 item
1             1       1       2       2  S02
2             2       1       2       1  S03

3

为了加速,纯粹使用numpy广播

diffs = np.not_equal(df.filter(like='rater'), df['right_answer'][:, None])
diffs = np.sum(diffs, axis=1) >= 2

df[diffs]

   right_answer  rater1  rater2  rater3 item
1             1       1       2       2  S02
2             2       1       2       1  S03

让我们计时吧!

# create dataframe with 4 million rows
dfbig = pd.concat([df]*1000000, ignore_index=True)
dfbig.shape

# (4000000, 5)

def numpy_broadcasting(data):
    diffs = np.not_equal(data.filter(like='rater'), data['right_answer'][:, None])
    diffs = np.sum(diffs, axis=1) >= 2


def pandas_method(data):
    mask = (
    data.filter(like='rater')
    .ne(df['right_answer'], axis=0).sum(axis=1).ge(2)
    )

%%timeit
numpy_broadcasting(dfbig)
# 92.5 ms ± 789 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
pandas_method(dfbig)
# 296 ms ± 7.27 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

numpy广播比普通方法快296 / 92.5 = 3.2倍。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接