簡體   English   中英

如果沒有逐行迭代數據幀,這需要很長時間,我如何檢查許多行是否都滿足條件?

[英]Without iterating row by row through a dataframe, which takes ages, how can I check that a number of rows all meet a condition?

我想做以下事情,但顯然我意識到這種迭代方法對於大型 DataFrames 非常慢,還有什么其他解決方案可以解決這個問題?:

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"

我希望上面的代碼做的是:

n 從 0 到 1,000 代入第 3 行,其中i 為 0 ,然后如果第 3 行中的條件對於 0 到 1,000 范圍內的每個 n 都成立,那么它將繼續執行第 4 行中的操作。

在此之后,它將把i為 1 ,然后將n 從 0 到 1,000放入第 3 行,如果該條件適用於該范圍內的所有 n,則它將執行第 4 行。

在此之后,它將取i 為 2 ,然后將n 從 0 到 1,000放入第 3 行,如果該條件適用於該范圍內的所有 n,則它將執行第 4 行。

在此之后,它將取3 中的 i,然后將n 從 0 到 1,000放入第 3 行,如果該條件適用於該范圍內的所有 n,則它將執行第 4 行。

......

在此之后,它將使用len(df) 的 i ,然后將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...

主要的一點是,您可以將每行具體要做的事情分開,並將其包含在一個函數中(可以根據需要進行調整和更新),並在需要時為幀上的所有行調用該函數。

您可以僅使用接近的數據來完成您正在嘗試的操作。 通過矢量化動態計算 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()

這是這樣的(使用相同的種子,它在您的機器上也應該看起來相同)

顯示購買點的樣本曲線

迭代是 Pandas 的最后手段。

您正在尋找的解決方案來自 numpy:

import numpy as np
df["Strategy 1"] = np.where(df["Close"] > df["MA"], "Buy", df["Strategy 1"])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM