我试图以pythonic方式(即无循环)遍历数据帧,以便根据是否满足条件创建新列。特别是在给定每日收益的数据框的情况下,我想创建一个新列,该列告诉我是否超过了上限或下限(限额是对称的,但特定于股票,因此每一行可能有不同的限额,称为在以下df中添加std),如下所示:
import pandas as pd
dict = [
{'ticker':'jpm','date': '2016-11-28','returns': '0.2','returns2': '0.3','std': '0.1'},
{ 'ticker':'ge','date': '2016-11-28','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'fb', 'date': '2016-11-28','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'aapl', 'date': '2016-11-28','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'msft','date': '2016-11-28','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'amzn','date': '2016-11-28','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'jpm','date': '2016-11-29','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'ge', 'date': '2016-11-29','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'fb','date': '2016-11-29','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'aapl','date': '2016-11-29','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'msft','date': '2016-11-29','returns': '0.2','returns2': '0.3','std': '0.1'},
{'ticker':'amzn','date': '2016-11-29','returns': '0.2','returns2': '0.3','std': '0.1'}
]
df = pd.DataFrame(dict)
df['date'] = pd.to_datetime(df1['date'])
df=df.set_index(['date','ticker'], drop=True)
应该进行转换,这样我就获得了一个新列,其中包含了当天的收益,如果超过了上/下限阈值,如果没有超过,则应该只包含了最后一天的收益(因此,returns2) 。
dict2 = [
{'ticker':'jpm','date': '2016-11-28','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{ 'ticker':'ge','date': '2016-11-28','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'fb', 'date': '2016-11-28','returns': '0.05','returns2': '-0.3','std': '0.1','sl': '-0.3'},
{'ticker':'aapl', 'date': '2016-11-28','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'msft','date': '2016-11-28','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{'ticker':'amzn','date': '2016-11-28','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'jpm','date': '2016-11-29','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{'ticker':'ge', 'date': '2016-11-29','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'fb','date': '2016-11-29','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{'ticker':'aapl','date': '2016-11-29','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'msft','date': '2016-11-29','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{'ticker':'amzn','date': '2016-11-29','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'}
]
df2 = pd.DataFrame(dict2)
df2['date'] = pd.to_datetime(df2['date'])
df2=df2.set_index(['date','ticker'], drop=False)
我正在尝试保持这种灵活性(因此它不仅可以用于返回2列)而且效率很高(以便可以在非常大的dfs上运行。
有人可以建议一种方法吗?
答案 0 :(得分:0)
我会使用numpy
:
dict1 = [
{'ticker':'jpm','date': '2016-11-28','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{ 'ticker':'ge','date': '2016-11-28','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'fb', 'date': '2016-11-28','returns': '0.05','returns2': '-0.3','std': '0.1','sl': '-0.3'},
{'ticker':'aapl', 'date': '2016-11-28','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'msft','date': '2016-11-28','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{'ticker':'amzn','date': '2016-11-28','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'jpm','date': '2016-11-29','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{'ticker':'ge', 'date': '2016-11-29','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'fb','date': '2016-11-29','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{'ticker':'aapl','date': '2016-11-29','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'},
{'ticker':'msft','date': '2016-11-29','returns': '0.2','returns2': '-0.3','std': '0.1','sl': '0.2'},
{'ticker':'amzn','date': '2016-11-29','returns': '-0.2','returns2': '0.3','std': '0.1','sl': '-0.2'}
]
df = pd.DataFrame(dict1)
df['date'] = pd.to_datetime(df['date'])
df=df.set_index(['date','ticker'], drop=True)
ret1 = pd.to_numeric(df.returns).values
ret2 = pd.to_numeric(df.returns2).values
std = pd.to_numeric(df['std']).values
mask = np.abs(ret1) >= std
out = mask*ret1 + (1-mask)*ret2
print(out)
# prints [ 0.2 -0.2 -0.3 -0.2 0.2 -0.2 0.2 -0.2 0.2 -0.2 0.2 -0.2]
#then just add the column to df:
df['my_out'] = pd.DataFrame(out, index=df.index)
答案 1 :(得分:0)
正在使用df2。
# Make columns numeric
df2[["returns", "returns2", "std"]] = df2[["returns", "returns2", "std"]].astype(float)
# Create new column using returns2 (we'll overwrite it in . moment)
df2["output"] = df2["returns2"]
# Mask whether returns crosses std
m = df2["returns"].abs() > df2["std"]
# Overwrite that mask onto new column
df2.loc[m, "output"] = df2.loc[m, "returns"]
如果要将其扩展到多于2列,那么我们需要了解选择哪一列的标准,但是过程将是相同的:构建一个与您的条件匹配的遮罩并应用它。 / p>