簡體   English   中英

Pandas Dataframe:對於給定的行,嘗試基於在另一列中查找值來分配特定列中的值

[英]Pandas Dataframe: for a given row, trying to assign value in a certain column based on a lookup of a value in another column

基本上,對於給定的行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

謝謝!

該解決方案仍然具有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]

通常,您可以在pandas使用類似於apply的函數來跳過for循環。 此后,我定義了一個wrapper函數,該函數按行組合變量。 最后,將此函數應用於數據框以創建result變量。 這里的關鍵元素是考慮wrapper函數內的行級別,並使用axis=1參數apply這種行為指示給apply函數。

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次)

暫無
暫無

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

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