Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Pandas-当N存储在列中时,基于另一列N行的值创建新列_Python_Pandas_Dataframe - Fatal编程技术网

Python Pandas-当N存储在列中时,基于另一列N行的值创建新列

Python Pandas-当N存储在列中时,基于另一列N行的值创建新列,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个带有示例数据的熊猫数据框架: idx price lookback 0 5 1 7 1 2 4 2 3 3 1 4 7 3 5 6 1 回溯可以是正的或负的,但我想取它的绝对值,取多少行的值 我正在尝试创建一个新列,其中包含前lookback+1行中price的值,例如: idx price lookback lb_pric

我有一个带有示例数据的熊猫数据框架:

idx    price    lookback
0      5    
1      7        1
2      4        2
3      3        1
4      7        3
5      6        1
回溯可以是正的负的,但我想取它的绝对值,取多少行的值

我正在尝试创建一个新列,其中包含前
lookback+1
行中
price
的值,例如:

idx    price    lookback  lb_price
0      5        NaN       NaN
1      7        1         NaN
2      4        2         NaN
3      3        1         7
4      7        3         5
5      6        1         3
我从感觉最明显的方式开始,但这不起作用:

df['sbc']=df['price'].shift(数据帧['lb'].abs()+1)
然后我尝试使用lambda,这不起作用,但我可能做错了:

sbc=lambda c,x:pd.系列(zip(*[c.shift(x+1)])
df['sbc']=sbc(df['price'],df['lb'].abs())
我还尝试了一个循环(速度非常慢,但效果很好),但我相信有更好的方法:

lookback=np.nan
对于范围内的i(len(df)):
如果df.loc[i,‘回望’]:
如果不是np.isnan(df.loc[i,‘回望’):
lookback=abs(int(df.loc[i,‘lookback’]))
如果不是np.isnan(回望)和(回望+1)
我看到过使用
lambda
df.apply
、或者
Series.map
的示例,但我并不清楚,因为我是Python和Pandas的新手

我正在寻找最快的方法,我可以做到这一点,如果有一种方法不使用循环

此外,为了发挥其价值,我计划使用此计算列创建另一列,我可以按如下操作:

df['streak-roc']=100*(df['price']-df['lb_price'])/df['lb_price']
但如果我能将所有这些结合成一种真正有效的方法,那将是理想的

解决方案

提供的几个解决方案效果很好(谢谢!),但都需要一些小的调整来应对我可能出现的负数,这是一个回溯+1而不是-1,因此我觉得在这里发布我的修改是谨慎的

所有这些都比我最初的循环要快得多,我的原始循环需要5m 26秒来处理我的数据集

我将我观察到的最快的一个标记为被接受,因为我的主要目标是提高我的循环速度

编辑的解决方案

法力桑巴雷-41秒

df['lb_price']=df.apply(
lambda x:df['price'][x.name-(abs(int(x['lookback']))+1)]
如果不是np.isnan(x['lookback'])和x.name>=(abs(int(x['lookback']))+1)
否则np.nan,
轴=1)
从mannh开始-43秒

def get_lb_价格(行,df):
如果不是np.isnan(第['lookback']行):
lb_idx=row.name-(abs(int(row['lookback']))+1)
如果lb_idx>=0:
返回df.loc[lb_idx,'价格']
其他:
返回np.nan
df['lb_price']=dataframe.apply(获取lb_price,axis=1,args=(df,))
来自比尔-18秒

lookup_idxs=df.index.values-(abs(df['lookback'].values)+1)
有效的\u lookups=lookup\u idxs>=0
df['lb_价格']=np.nan
df.loc[valid_lookup,'lb_price']=df['price']。to_numpy()[lookup_idxs[valid_lookup].astype(int)]

通过使用row.name获取df.apply()调用中的行索引,可以生成与当前所在行相关的“lb_价格”数据

%time
df.apply(
    lambda x: df['price'][x.name - int(x['lookback'] + 1)]
    if not np.isnan(x['lookback']) and x.name >= x['lookback'] + 1 
    else np.nan,
    axis=1)

# > CPU times: user 2 µs, sys: 0 ns, total: 2 µs
# > Wall time: 4.05 µs

FYI:您的示例中有一个错误,因为idx[5]的磅值应该是3而不是7。

此解决方案循环列
锁回
的值,并计算列
价格
中所需值的索引,我将该列存储为列表。 该规则要求锁定值必须是一个数字,并且所需的索引不小于0

new = np.zeros(df.shape[0])
price = df.price.values
for i, lookback in enumerate(df.lookback.values):
    # lookback has to be a number and the index is not allowed to be less than 0
    # 0<i-lookback is equivilant to 0<=i-(lookback+1)
    if lookback!=np.nan and 0<i-lookback: 
        new[i] = price[int(i-(lookback+1))]
    else:
        new[i] = np.nan
df['lb_price'] = new
new=np.zero(df.shape[0])
价格=df.price.values
对于i,枚举中的回溯(df.lookback.values):
#回溯必须是一个数字,且索引不允许小于0

#0下面是一个使用正则函数的示例

def get_lb_价格(行,df):
lb_idx=row.name-abs(row['lookback'])-1
如果lb_idx>=0:
返回df.loc[lb_idx,'价格']
其他:
返回np.nan
df['lb_price']=df.apply(获取lb_price,axis=1,args=(df,))

这是一个使用numpy数组索引的矢量化版本(即循环编号)

lookup_idxs = df.index.values - df['lookback'].values - 1
valid_lookups = lookup_idxs >= 0
df['lb_price'] = np.nan
df.loc[valid_lookups, 'lb_price'] = df.price.to_numpy()[lookup_idxs[valid_lookups].astype(int)]
print(df)
输出:

     price  lookback  lb_price
idx                           
0        5       NaN       NaN
1        7       1.0       NaN
2        4       2.0       NaN
3        3       1.0       7.0
4        7       3.0       5.0
5        6       1.0       3.0

我会考虑把它分解成多行或使用正则函数,这样它的工作就更清楚了。谢谢你的建议:感谢您指出。
name错误:名称“p”未定义
此解决方案有效,但未考虑潜在的负数,因此我做了一个小改动。没有注意到您说过回望可以是负数。我修正了密码。