我有一个仅包含数字的巨大数据框(我在下面显示的数据框仅用于演示目的)。我的目标是在数据帧的每一行中将大于特定值 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/