【发布时间】:2020-06-21 17:51:56
【问题描述】:
我有一个数据框,其中包含一列值(“一”列)。对于 (product(sma1, sma2)) 给出的每一对值,我想:
- 使用 SMA1 和 SMA2 计算 2 个简单移动平均线
- 当满足条件 A 或 B 时,将 SMA1、SMA2 和价格的值附加到结果中
下面的代码展示了我的方法。是否可以做同样的事情来删除嵌套的 for 循环(可能使用 apply)?那会更快/更好吗?
from itertools import product
import pandas as pd
data = pd.DataFrame( [3,2,5,8,5,12,7,8,9,10,11,12,13,14,17,19,15,18] ,columns=['One'])
sma1 = range(2, 5)
sma2 = range(5, 8)
results=pd.DataFrame()
for SMA1, SMA2 in product(sma1, sma2): #for each pair SMA1, SMA2, perfomr the following
data['SMA1'] = data['One'].rolling(SMA1).mean()
data['SMA2'] = data['One'].rolling(SMA2).mean()
data.dropna(inplace=True)
for i in range( len(data)):
#Condition A:
if data.iloc[i, 1] > data.iloc[i, 2] and data.iloc[i-1, 1] < data.iloc[i-1,2]:
#Buy
price = data.iloc[i, 0]
#Condition B
elif data.iloc[i, 1] < data.iloc[i, 2] and data.iloc[i-1, 1] > data.iloc[i-1,2]:
#Sell
price = data.iloc[i, 0]
#if neither condition is true, dont append anything
else:
continue
results = results.append(pd.DataFrame(
{'SMA1': SMA1,
'SMA2': SMA2,
'price': price,
},
index=[0]), ignore_index = True)
results
输出:
SMA1 SMA2 price
0 2 5 5
1 2 5 8
2 2 5 9
3 2 5 18
来自 Hugolmn 的回答中的 EIDT 我看到了使用 [i-1] 的问题。 但是,通过您的方法,我没有得到正确的答案, 我已将问题简化为仅查找 2 列是否满足条件 A、B。
data = pd.DataFrame({'col1': [3,2,6,8,6,11], 'col2': [3,3,5,8,5,12]})
#columns with shifted data
data['col1_shift']=data['col1'].shift(1)
data['col2_shift']=data['col2'].shift(1)
#condition A
data['Con1_col1>col2'] = data['col1']>data['col2']
data['Con1_col1<col2_shift'] = data['col1_shift'] < data['col2_shift']
data['ConA'] = data['Con1_col1>col2'] & data['Con1_col1<col2_shift']
#condition B
data['Con2_col1<col2'] = data['col1']<data['col2']
data['Con2_col1>col2_shift'] = data['col1_shift'] > data['col2_shift']
data['ConB'] = data['Con2_col1<col2'] & data['Con2_col1>col2_shift']
# data['part1']= ((data.col1 - data.col2) > 0)
data['Hugolmn_method']= ((data.col1 - data.col2) >= 0).diff() > 0
data['expected']= data['ConA'] | data['ConB']
data
输出:
col1 col2 col1_shift col2_shift Con1_col1>col2 Con1_col1<col2_shift \
0 3 3 NaN NaN False False
1 2 3 3.0 3.0 False False
2 6 5 2.0 3.0 True True
3 8 8 6.0 5.0 False False
4 6 5 8.0 8.0 True False
5 11 12 6.0 5.0 False False
ConA Con2_col1<col2 Con2_col1>col2_shift ConB Hugolmn_method \
0 False False False False False
1 False True False False True
2 True False False False True
3 False False True False False
4 False False False False False
5 False True True True True
expected
0 False
1 False
2 True
3 False
4 False
5 True
【问题讨论】:
-
嗨,最好避免在 pandas 中出现手写循环。可以查看这个方法stackoverflow.com/questions/19913659/…
-
谢谢,我不清楚 for with itertool prodcuts 是否很快?什么是更好的方法,因为我想不出一种使用“where”的方法
-
嗨!我刚刚看到您的编辑并修改了我的答案。现在它工作正常!这只是使用
>=而不是>的问题。看看吧!