python - 如何替换数据框每行中大于特定阈值的前 n 个元素

标签 python performance pandas dataframe

我有一个仅包含数字的巨大数据框(我在下面显示的数据框仅用于演示目的)。我的目标是在数据帧的每一行中将大于特定值 val 的前 n 数字替换为 0。

举个例子:

我的数据框可能如下所示:

   c1  c2  c3  c4
0  38  10   1   8
1  44  12  17  46
2  13   6   2   7
3   9  16  13  26

如果我现在选择 n = 2(替换次数)和 val = 10,我想要的输出将如下所示:

   c1  c2  c3  c4
0   0  10   1   8
1   0   0  17  46
2   0   6   2   7
3   9   0   0  26

在第一行中,只有一个值大于 val 所以只有一个被替换,在第二行中所有值都大于 val 但只有前两个可以更换。第 3 行和第 4 行的模拟(请注意,不仅前两列受到影响,而且一行中的前两个值可以在任何列中)。

一个简单且非常丑陋的实现可能如下所示:

import numpy as np
import pandas as pd

np.random.seed(1)

col1 = [np.random.randint(1, 50) for ti in xrange(4)]
col2 = [np.random.randint(1, 50) for ti in xrange(4)]
col3 = [np.random.randint(1, 50) for ti in xrange(4)]
col4 = [np.random.randint(1, 50) for ti in xrange(4)]

df = pd.DataFrame({'c1': col1, 'c2': col2, 'c3': col3, 'c4': col4})

val = 10
n = 2

for ind, row in df.iterrows():
    # number of replacements
    re = 0

    for indi, vali in enumerate(row):
        if vali > val:
            df.iloc[ind, indi] = 0
            re += 1
            if re == n:
                break

这行得通,但我相信还有更有效的方法可以做到这一点。有任何想法吗?

最佳答案

您可以编写自己的有点奇怪的函数并使用 apply axis=1:

def f(x, n, m):
    y = x.copy()
    y[y[y > m].iloc[:n].index] = 0
    return y

In [380]: df
Out[380]:
   c1  c2  c3  c4
0  38  10   1   8
1  44  12  17  46
2  13   6   2   7
3   9  16  13  26

In [381]: df.apply(f, axis=1, n=2, m=10)
Out[381]:
   c1  c2  c3  c4
0   0  10   1   8
1   0   0  17  46
2   0   6   2   7
3   9   0   0  26

注意:y = x.copy() 需要复制该系列。如果您需要就地更改您的值,您可以省略该行。你需要额外的 y 因为切片你会得到一个副本而不是原始对象。

关于python - 如何替换数据框每行中大于特定阈值的前 n 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35015414/

相关文章:

python - 在 x 轴上绘制带有标签而不是计数的直方图 matplotlib

python - 从 csv 文件绘制纬度和经度

python - 如何在单个 jupyter 单元格中显示多个 pandas describe() 输出?

Python - 查找列表中的值位置并输出为新列表

python - 为什么 Collections.counter 这么慢?

python - 如何在文件之间共享静态类变量?

performance - 为什么选择 `unwrap_or_else` 而不是 `unwrap_or` ?

android - 在 while 循环中读取 SharedPreferences 的坏习惯?

python - "You should never modify something you are iterating over"。那我该如何修改呢?

python - 如何在当前目录及其子目录中创建具有给定扩展名的文件列表?