如果不逐行遍历需要很长时间的数据帧,我如何检查是否所有行都满足条件?
Without iterating row by row through a dataframe, which takes ages, how can I check that a number of rows all meet a condition?
我想做下面的事情,但显然我意识到这种迭代方法对于大型 DataFrame 来说非常慢,还有什么其他的解决方案可以解决这个问题?:
for i in range(len(df)):
for n in range(1001):
if df["Close"][(i+n)] > df["MA"][i+n]:
df["Strategy 1"][i] = "Buy"
我希望上面的代码做的是:
Sub in n from 0 to 1,000进入第3行,其中i为0,然后if第3行的条件为0到1000范围内的每个n保留然后它会继续执行第4行的操作。
在此之后它会取 i of 1 然后 sub in n 从 0 到 1,000 到第 3 行,如果条件为该范围内的所有 n 保持不变,然后它将执行第 4 行。
在此之后它会采取 i of 2 然后 sub in n 从 0 到 1,000 到第 3 行,如果条件为该范围内的所有 n 保持不变,然后它将执行第 4 行。
在此之后它会采取 i of 3 然后 sub in n 从 0 到 1,000 到第 3 行,如果条件为该范围内的所有 n 保持不变,然后它将执行第 4 行。
... ...
在此之后它会采取 i of len(df) 然后 sub in n 从 0 到 1,000 进入第 3 行,并且如果该范围内的所有 n 条件都成立,那么它将执行第 4 行。
不管上面给出的代码是否符合我的预期,是否有更快的方法来计算非常大的多 GB 数据帧?
使用 .apply 函数会更快。对于一般示例...
import pandas as pd
# only required to create the test dataframe in this example
import numpy as np
# create a dataframe for testing using the numpy import above
df = pd.DataFrame(np.random.randint(100,size=(10, )),columns=['A'])
# create a new column based on column 'A' but moving the column 'across and up'
df['NextRow'] = df['A'].shift(-1)
# create a function to do something, anything, and return that thing
def doMyThingINeedToDo(num, numNext):
# 'num' is going to be the value of whatever is in column 'A' per row
# as the .apply function runs below and 'numNext' is plus one.
if num >= 50 and numNext >= 75:
return 'Yes'
else:
return '...No...'
# create a new column called 'NewColumnName' based on the existing column 'A' and apply the
# function above, whatever it does, to the frame per row.
df['NewColumnName'] = df.apply(lambda row : doMyThingINeedToDo(row['A'], row['NextRow']), axis = 1)
# output the frame and notice the new column
print(df)
输出:
A NextRow NewColumnName
0 67 84.0 Yes
1 84 33.0 ...No...
2 33 59.0 ...No...
3 59 85.0 Yes
4 85 39.0 ...No...
5 39 81.0 ...No...
6 81 76.0 Yes
7 76 83.0 Yes
8 83 60.0 ...No...
9 60 NaN ...No...
要点是,您可以将每行确切要执行的操作分开,并将其包含在一个函数中(可以根据需要进行调整和更新),并在需要时为框架上的所有行调用该函数.
迭代是 Pandas 的最后手段。
您正在寻找的解决方案来自 numpy:
import numpy as np
df["Strategy 1"] = np.where(df["Close"] > df["MA"], "Buy", df["Strategy 1"])
您可以仅使用您的关闭数据来完成您正在尝试的事情。通过矢量化即时计算 MA 和 1000 条件。也许试试这个:
import numpy as np
ma_window = 1000
n = 1000
df['Strategy 1'] = \
np.where( \
(df['close'] > df['close'].rolling(window=ma_window).mean()).rolling(window=n).mean() == 1, \
'buy','')
试试这个,看看它是否适合你。
首先,让我说明一下我是如何理解你的规则的。据我所知,只有在连续 1000 个 MA
大于 Close
的情况下,您才尝试在 df 的“策略 1”列中获取“买入”值那时。我认为您只需在比较中使用滚动总和即可完成此操作:
import pandas as pd
import numpy as np
# build some repeatable sample data
np.random.seed(1)
df = pd.DataFrame({'close': np.cumsum(np.random.randn(10000))})
df['MA'] = df['close'].rolling(1000).mean()
# Apply strategy
npoints = 1000
df['Strategy 1'] = float('nan')
buypoints = (df['MA'] > df['close']).rolling(npoints).sum() == npoints
df.loc[buypoints, "Strategy 1"] = "Buy"
# just for visualisation show where the Buys would be
df['Buypoints'] = buypoints*10
df.plot()
结果是这样的(使用相同的种子,它在您的机器上看起来应该也一样)
我想做下面的事情,但显然我意识到这种迭代方法对于大型 DataFrame 来说非常慢,还有什么其他的解决方案可以解决这个问题?:
for i in range(len(df)):
for n in range(1001):
if df["Close"][(i+n)] > df["MA"][i+n]:
df["Strategy 1"][i] = "Buy"
我希望上面的代码做的是:
Sub in n from 0 to 1,000进入第3行,其中i为0,然后if第3行的条件为0到1000范围内的每个n保留然后它会继续执行第4行的操作。
在此之后它会取 i of 1 然后 sub in n 从 0 到 1,000 到第 3 行,如果条件为该范围内的所有 n 保持不变,然后它将执行第 4 行。
在此之后它会采取 i of 2 然后 sub in n 从 0 到 1,000 到第 3 行,如果条件为该范围内的所有 n 保持不变,然后它将执行第 4 行。
在此之后它会采取 i of 3 然后 sub in n 从 0 到 1,000 到第 3 行,如果条件为该范围内的所有 n 保持不变,然后它将执行第 4 行。
... ...
在此之后它会采取 i of len(df) 然后 sub in n 从 0 到 1,000 进入第 3 行,并且如果该范围内的所有 n 条件都成立,那么它将执行第 4 行。
不管上面给出的代码是否符合我的预期,是否有更快的方法来计算非常大的多 GB 数据帧?
使用 .apply 函数会更快。对于一般示例...
import pandas as pd
# only required to create the test dataframe in this example
import numpy as np
# create a dataframe for testing using the numpy import above
df = pd.DataFrame(np.random.randint(100,size=(10, )),columns=['A'])
# create a new column based on column 'A' but moving the column 'across and up'
df['NextRow'] = df['A'].shift(-1)
# create a function to do something, anything, and return that thing
def doMyThingINeedToDo(num, numNext):
# 'num' is going to be the value of whatever is in column 'A' per row
# as the .apply function runs below and 'numNext' is plus one.
if num >= 50 and numNext >= 75:
return 'Yes'
else:
return '...No...'
# create a new column called 'NewColumnName' based on the existing column 'A' and apply the
# function above, whatever it does, to the frame per row.
df['NewColumnName'] = df.apply(lambda row : doMyThingINeedToDo(row['A'], row['NextRow']), axis = 1)
# output the frame and notice the new column
print(df)
输出:
A NextRow NewColumnName
0 67 84.0 Yes
1 84 33.0 ...No...
2 33 59.0 ...No...
3 59 85.0 Yes
4 85 39.0 ...No...
5 39 81.0 ...No...
6 81 76.0 Yes
7 76 83.0 Yes
8 83 60.0 ...No...
9 60 NaN ...No...
要点是,您可以将每行确切要执行的操作分开,并将其包含在一个函数中(可以根据需要进行调整和更新),并在需要时为框架上的所有行调用该函数.
迭代是 Pandas 的最后手段。
您正在寻找的解决方案来自 numpy:
import numpy as np
df["Strategy 1"] = np.where(df["Close"] > df["MA"], "Buy", df["Strategy 1"])
您可以仅使用您的关闭数据来完成您正在尝试的事情。通过矢量化即时计算 MA 和 1000 条件。也许试试这个:
import numpy as np
ma_window = 1000
n = 1000
df['Strategy 1'] = \
np.where( \
(df['close'] > df['close'].rolling(window=ma_window).mean()).rolling(window=n).mean() == 1, \
'buy','')
试试这个,看看它是否适合你。
首先,让我说明一下我是如何理解你的规则的。据我所知,只有在连续 1000 个 MA
大于 Close
的情况下,您才尝试在 df 的“策略 1”列中获取“买入”值那时。我认为您只需在比较中使用滚动总和即可完成此操作:
import pandas as pd
import numpy as np
# build some repeatable sample data
np.random.seed(1)
df = pd.DataFrame({'close': np.cumsum(np.random.randn(10000))})
df['MA'] = df['close'].rolling(1000).mean()
# Apply strategy
npoints = 1000
df['Strategy 1'] = float('nan')
buypoints = (df['MA'] > df['close']).rolling(npoints).sum() == npoints
df.loc[buypoints, "Strategy 1"] = "Buy"
# just for visualisation show where the Buys would be
df['Buypoints'] = buypoints*10
df.plot()
结果是这样的(使用相同的种子,它在您的机器上看起来应该也一样)