我有一个只包含数字的巨大数据框(我在下面展示的数据仅用于演示目的)。我的目标是在数据帧的每一行中将大于某个值n
的第一个val
数字替换为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
这有效,但我确信有更有效的方法可以做到这一点。有任何想法吗?
答案 0 :(得分:2)
您可以自己编写一些奇怪的函数并将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
因为切片你会得到一个副本而不是原始对象。