我的问题
我有一个循环,它使用另一列的值或该列中的前一个值的组合来创建一列,具体取决于条件("从新低算起的天数=0")。在一个巨大的数据集上,它真的很慢,所以我想摆脱循环,找到一个更快的公式。
当前工作代码
import numpy as np
import pandas as pd
csv1 = pd.read_csv('stock_price.csv', delimiter = ',')
df = pd.DataFrame(csv1)
for x in range(1,len(df.index)):
if df["days from new low"].iloc[x] == 0:
df["q"].iloc[x] = df["RSI on new low"].iloc[x]
else:
df["q"].iloc[x] = df["q"].iloc[x-1]
df
输入数据和预期输出
RSI on new low,days from new low,q
29.6,0,29.6
29.6,1,29.6
29.6,2,29.6
29.6,3,29.6
29.6,4,29.6
21.7,0,21.7
21.7,1,21.7
21.7,2,21.7
21.7,3,21.7
21.7,4,21.7
21.7,5,21.7
21.7,6,21.7
21.7,7,21.7
21.7,8,21.7
21.7,9,21.7
25.9,0,25.9
25.9,1,25.9
25.9,2,25.9
23.9,0,23.9
23.9,1,23.9
尝试的解决方案
我试着用.shift()函数创建一个公式,但没能成功。
你知道我该怎么做吗?
干杯!
也许您可以使用where
?
df['q']= df["RSI on new low"].where(df["days from new low"] == 0).fillna(method='ffill')
请参阅此处的文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.where.html
np.where子句执行一个矢量化操作,该操作将删除慢速python for循环。
import numpy as np
import pandas as pd
csv1 = pd.read_csv('stock_price.csv', delimiter = ',')
df = pd.DataFrame(csv1)
df['p'] = np.where(df['days from new low'].eq(0), df['RSI on new low'], np.nan)
df['p'] = df['p'].ffill()
print(df)
打印:
RSI on new low days from new low q p
0 29.6 0 29.6 29.6
1 29.6 1 29.6 29.6
2 29.6 2 29.6 29.6
3 29.6 3 29.6 29.6
4 29.6 4 29.6 29.6
5 21.7 0 21.7 21.7
6 21.7 1 21.7 21.7
7 21.7 2 21.7 21.7
8 21.7 3 21.7 21.7
9 21.7 4 21.7 21.7
10 21.7 5 21.7 21.7
11 21.7 6 21.7 21.7
12 21.7 7 21.7 21.7
13 21.7 8 21.7 21.7
14 21.7 9 21.7 21.7
15 25.9 0 25.9 25.9
16 25.9 1 25.9 25.9
17 25.9 2 25.9 25.9
18 23.9 0 23.9 23.9
19 23.9 1 23.9 23.9
您可以应用函数到每一行,并使用该函数上次执行时的值。
保持此结果的可能解决方案之一是使用此函数的属性。
因此,定义一个要应用的函数:
def fn(row):
if row['days from new low'] == 0:
fn.rVal = row['RSI on new low']
return fn.rVal
然后将fn.rVal设置为您选择的任何初始值:
fn.rVal = 0
最后一步是应用这个功能:
df['q'] = df.apply(fn, axis=1)
此解决方案的工作速度比您的循环和iloc快得多。