Python 3.x 试图找到一种有效的方法,在引用前一行的pandas中使用while循环

Python 3.x 试图找到一种有效的方法,在引用前一行的pandas中使用while循环,python-3.x,pandas,Python 3.x,Pandas,我想在数千行数据上快速多次运行此自定义函数。我认为解决这个问题的方法需要很长时间 我已尝试使用.apply,但我看不出如何仅应用于某些行。我曾考虑尝试将前一行解决方案存储为变量,但无法推理出代码,并认为它可能具有相同的速度 下面的代码是我试图提高效率的示例。这就像这里的excel版本 4分30秒 我是一个新的编码和自学,如果有人能告诉我一个方向,可以帮助我想一个方法来计算这在一个非循环品种,这将是非常有帮助的我,并适用于我未来的理解编码,谢谢 import pandas as pd import

我想在数千行数据上快速多次运行此自定义函数。我认为解决这个问题的方法需要很长时间

我已尝试使用.apply,但我看不出如何仅应用于某些行。我曾考虑尝试将前一行解决方案存储为变量,但无法推理出代码,并认为它可能具有相同的速度

下面的代码是我试图提高效率的示例。这就像这里的excel版本 4分30秒

我是一个新的编码和自学,如果有人能告诉我一个方向,可以帮助我想一个方法来计算这在一个非循环品种,这将是非常有帮助的我,并适用于我未来的理解编码,谢谢

import pandas as pd
import numpy as np
import time

start_program = time.time()

df = pd.DataFrame({'Date':['2019-09-01','2019-09-02','2019-09-03','2019-09-04','2019-09-05','2019-09-06'], 'price':[10,8,5,20,50,60]})

df['Date'] = pd.to_datetime(df["Date"])

df.set_index('Date',inplace=True)

df.insert(1,'AVG', "")

df['AVG'] = df['AVG'].apply(pd.to_numeric)

df.iloc[3, df.columns.get_loc('AVG')] = np.mean(df['price'].iloc[0:4])

def avgfunc(df,target_column,price_column,row,num_avg):
    df.iloc[row, df.columns.get_loc(target_column)] = ((df[target_column].iloc[row -1]*(num_avg - 1))+df[price_column].iloc[row])/num_avg
    return df.iloc[row, df.columns.get_loc(target_column)]

leng = len(df['price'])

i=4
while i < leng:
    avgfunc(df,'AVG','price',i,5)
    i += 1      

print(df)

end_program = time.time()
print("Total time to complete program is :", end_program - start_program)

$ python test_loop.py
        price  AVG
Date
2019-09-01     10    NaN
2019-09-02      8    NaN
2019-09-03      5    NaN
2019-09-04     20  10.75
2019-09-05     50  18.60
2019-09-06     60  26.88
Total time to complete program is : 0.03003978729248047
将熊猫作为pd导入
将numpy作为np导入
导入时间
启动程序=time.time()
df=pd.数据帧({'Date':['2019-09-01','2019-09-02','2019-09-03','2019-09-04','2019-09-05','2019-09-06','price':[10,8,5,20,50,60])
df['Date']=pd.to_datetime(df[“Date”])
df.set_索引('Date',inplace=True)
df.插入(1,'AVG',“”)
df['AVG']=df['AVG'].应用(pd.到数值)
df.iloc[3,df.columns.get_loc('AVG')]=np.mean(df['price'].iloc[0:4])
def avgfunc(df、目标列、价格列、行、平均数):
df.iloc[row,df.columns.get_loc(target_column)]=((df[target_column].iloc[row-1]*(num_avg-1))+df[price_column].iloc[row])/num avg
返回df.iloc[行,df.columns.get_loc(目标_列)]
长度=长度(df[‘价格’])
i=4
而我
这里有一种使用
numpy的方法

ave= np.frompyfunc(lambda a,b: (a+b)/2,2,1)
v=ave.accumulate(df.price.values, dtype=np.object)
v
Out[525]: array([1, 1.5, 2.25, 3.125, 4.0625, 5.03125], dtype=object)
或者我们可以使用
numba

from numba import njit
@njit
def ave(x):
    total = 1
    result = []
    for y in x:
        total = (y+total)/2
        result.append(total)
    return result
ave(df.price.values)
Out[528]: [1.0, 1.5, 2.25, 3.125, 4.0625, 5.03125]

您还可以使用itertools中的
累计

from itertools import accumulate
np.fromiter(accumulate(df.price,lambda x,y: (x+y)/2),float)
 array([1.     , 1.5    , 2.25   , 3.125  , 4.0625 , 5.03125])

看起来,对于第N行,您正试图计算标记为“price”的列的平均值,从N=4开始,在其自身窗口和数据帧中的前N-1行上,对吗?您只是以一种迭代的方式逐行执行,需要上一行的结果通知下一行

聪明,但pandas在遍历数据帧行时性能相当差,因此应该不惜一切代价避免这种情况。您是否考虑过使用扩展窗口计算


参数
min\u periods
指定初始窗口的宽度。这将跳过
“price”
列中的前3行,将
“AVG”
中这些行的值设置为
NaN
。然后,它将计算
“price”
中前4行的平均值,并将其用于
“AVG”
的第4个元素,以及
“price”
中前5行的平均值,并将其用于
“AVG”
的第5个元素,依此类推。

而不是发布一段(相当)长的代码,你可能应该解释一下你想要达到的目标。这是一个非常聪明的答案。哇,谢谢你的快速回复。我花了一些时间才明白你做了什么。但我想我应该更清楚。我需要NAN在那里。我想根据不同的平均值范围来调整这一点。例如,如果我取前4行的平均值,则需要代码将该平均值乘以4,然后加上第5个价格,并将结果除以5。然后需要沿着列向下推进。我将编辑我的示例代码。我降低了平均值以降低数据量。你能帮我调整一下吗?
df["AVG"] = df["price"].expanding(min_periods=4).mean()