基本上,对于给定的行i,我试图根据另一列“本地最大字符串”中i的值,将“ Adj”列中的i值分配给某个值。基本上,需要在DataFrame的另一列“日期字符串”中搜索“本地最大字符串”中的第i行的值,然后,包含值q的行在“调整结束”列中具有该值。第i行的“ Adj”列的值。
抱歉,这很难理解。下面的for循环完成了我想做的事情,但是我认为在Pandas中应该有更好的方法。我尝试使用apply和lambda函数,但是它说不可能进行赋值,而且我不确定我的操作方式是否正确。 for循环还需要很长时间才能完成。
代码如下:
for x in range(0, len(df.index)):
df['Adj'][x] = df.loc[df['Date String'] == df['Local Max String'][x]]['Adj Close']
下面是DF的图片,可以更好地理解我的意思。 “调整”列中的值将查找与“本地最大字符串”中的“日期”相对应的“调整结束”值。
import numpy as np
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
from pandas_datareader import data as pdr
import matplotlib.pyplot as plt
import datetime
import fix_yahoo_finance as yf
yf.pdr_override() # <== that's all it takes :-)
# Dates for data
start_date = datetime.datetime(2017,11,1)
end_date = datetime.datetime(2018,11,1)
df = pdr.get_data_yahoo('SPY', start=start_date, end=end_date)
df.data = df['Adj Close']
df['Most Recent Local Max'] = np.nan
df['Date'] = df.index
local_maxes = list(df[(df.data.shift(1) < df.data) & (df.data.shift(-1) < df.data)].index)
local_maxes.append(df['Date'][0] - datetime.timedelta(days=1))
def nearest(items, pivot):
return min([d for d in items if d< pivot], key=lambda x: abs(x - pivot))
df['Most Recent Local Max'] = df['Date'].apply(lambda x: min([d for d in local_maxes if d < x], key=lambda y: abs(y - x)) )
df['Local Max String'] = df['Most Recent Local Max'].apply(lambda x: str(x))
df['Date String'] = df['Date'].apply(lambda x: str(x))
df.loc[df['Local Max String'] == str(df['Date'][0] - datetime.timedelta(days=1)), 'Local Max String'] = str(df['Date'][0])
df['Adj'] = np.nan
谢谢!
答案 0 :(得分:0)
此解决方案仍然具有for,但是它将迭代次数从df.shape[1]
减少到df['Local Max String'].nunique()
,因此它可能足够快:
for a_local_max in df['Local Max String'].unique():
df.loc[df['Date String'] == a_local_max, 'Adj'] = df.loc[df['Local Max String'] == a_local_max, 'Adj Close'].iloc[0]
答案 1 :(得分:0)
通常,您可以在pandas
中使用类似于apply的函数来跳过for循环。此后,我定义了一个wrapper
函数,该函数按行组合变量。
最后,将此函数应用于数据框以创建result
变量。此处的关键元素是思考wrapper
函数中的行级别,并使用apply
参数向axis=1
函数指示此行为。
import pandas as pd
import numpy as np
# Dummy data containing two columns with overlapping data
df = pd.DataFrame({'date': 100*np.random.sample(10000), 'string': 2500*['hello', 'world', '!', 'mars'], 'another_string': 10000*['hello']})
# Here you define the operation at the row level
def wrapper(row):
# uncomment if the transformation is to be applied to every column:
# return 2*row['date']
# if you need to first test some condition:
if row['string'] == row['another_string']:
return 2*row['date']
else:
return 0
# Finally you generate the new column using the operation defined above.
df['result'] = df.apply(wrapper, axis=1)
此代码在每循环195 ms±1.96 ms内完成(平均±标准偏差,共运行7次,每个循环1次)