Pandas Dataframe: для заданной строки, пытаясь присвоить значение в определенном столбце на основе поиска значения в другом столбце - PullRequest
0 голосов
/ 21 ноября 2018

Обычно для данной строки i я пытаюсь присвоить значение i в столбце «Adj» определенному значению на основе значения i в другом столбце «Local Max String».По сути, значение строки i в «Local Max String» необходимо искать в другом столбце DataFrame, «Date String», а затем строка, содержащая значение, строка q, имеет значение в столбце «Adj Close»значение для строки 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, чтобы лучше понять, что я имею в виду.Значение в столбце Adj будет искать значение Adj Close, соответствующее дате в локальной строке Max.

enter image description here

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

Спасибо!

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Часто вы можете пропустить цикл for с помощью функции apply-like в pandas.Далее я определяю функцию 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 мс ±1,96 мс на цикл (среднее ± стандартное отклонение из 7 циклов, по 1 циклу)

0 голосов
/ 22 ноября 2018

Это решение все еще имеет значение 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...