我正在寻找一种将值应用于DataFrame中的列的更快的方法。该值基于第一列和第二列中的两个True and False
值。这是我目前的解决方案:
df['result'] = df.check1.astype(int)
for i in range(len(df)):
if df.result[i] != 1:
df.result[i] = df.result.shift(1)[i] + df.check2[i].astype(int)
产生以下结果:
check1 check2 result
0 True False 1
1 False False 1
2 False False 1
3 False False 1
4 False False 1
5 False False 1
6 False True 2
7 False False 2
8 False True 3
9 False False 3
10 False True 4
11 False False 4
12 False True 5
13 False False 5
14 False True 6
15 False False 6
16 False True 7
17 False False 7
18 False False 7
19 False False 7
20 False True 8
21 False False 8
22 False True 9
23 True False 1
24 False False 1
因此,第三列必须是一个数字,该数字基于其上方一行中的值。 如果check1为True,则数字应返回到1。如果check2为true,则需要在数字上添加1。否则,数字保持不变。
当前代码很好,但是花了我太长的时间,因为我需要将此代码应用于大约为70.000行。我很确定它可以改善(我猜是使用apply函数,但不确定)。
有什么想法吗?
答案 0 :(得分:3)
使用pandas.DataFrame.groupby.cumsum
:
import pandas as pd
df['result'] = df.groupby(df['check1'].cumsum())[['check1', 'check2']].cumsum().sum(1)
或@Dan的建议:
df['result'] = df.groupby(df['check1'].cumsum())['check2'].cumsum().add(1)
输出:
check1 check2 result
0 True False 1.0
1 False False 1.0
2 False False 1.0
3 False False 1.0
4 False False 1.0
5 False False 1.0
6 False True 2.0
7 False False 2.0
8 False True 3.0
9 False False 3.0
10 False True 4.0
11 False False 4.0
12 False True 5.0
13 False False 5.0
14 False True 6.0
15 False False 6.0
16 False True 7.0
17 False False 7.0
18 False False 7.0
19 False False 7.0
20 False True 8.0
21 False False 8.0
22 False True 9.0
23 True False 1.0
24 False False 1.0
答案 1 :(得分:0)
您要使用上一行的值来迭代数据帧。在这种情况下,最有效的方法是直接迭代基础的numpy数组:
df = pd.read_fwf(io.StringIO(t))
df['result'] = df.check1.astype(int)
res = df['result'].values
c1 = df['check1'].values
c2 = df['check2'].values
old = -1
for i in range(len(df)):
if res[i] != 1:
res[i] = old + int(c2[i])
old = res[i]
这很好用,因为numpy数组是可变类型,所以更改反映在数据框中。
Timeit表示,这是@Chris的原始解决方案的两倍,但在@Dan进行改进后仍快1.5倍。