我试图从我的数据框中的'yy'列中减去(1)年,如果该行的'月'列中的月份=='十月','十一月','十二月'。
我已经尝试了很多方法,并且在这一点上陷入困境。下面的循环使整个yy2列为yy-1,而不仅仅是月份列中包含10月,11月或12月的行。
yy2 = []
for row in df['month']:
if row != 'October':
yy2 = df['yy']
else:
yy2 = (df['yy'])-1
df['yy2'] = yy2
答案 0 :(得分:2)
month_selection = { 'October', 'November', 'December'}
df['yy2'] = df['yy'].where(~df['month'].isin(month_selection ), df['yy'] - 1)
更天真的实施
df['yy2'] = df['yy'].copy()
sel = df['month'].isin(month_selection )
df.loc[sel, 'yy2'] = df.loc[sel, 'yy'] - 1
答案 1 :(得分:1)
大熊猫的第一条规则:如果你在行上循环,那你就错了。
您要做的是使用apply
:
df['yy2'] = df.apply(lambda x: x['yy'] - 1 if x['Month'] in ['October', 'November', 'December'] else x['yy'], axis=1)
答案 2 :(得分:0)
通常,您不应该使用带有pandas的循环。一切都已经过矢量化了。
例如,您的当前循环基于每次迭代时的单个值计算整个列的yy2
。这可能不是你想要的。由于您的上个月是'October'
,因此会减去整个列:操作df['yy'] - 1
计算整个列yy
的差异。
您可以使用此矢量化。
首先计算要减去的布尔掩码:
df = pd.DataFrame({'month': ['September', 'October'], 'yy': [1, 1]})
mask = (df['month'] == 'October')
由于布尔值恰好等于整数1和0,因此有两种方法可以执行减法运算。你可以直接这样做:
df['yy2'] = df['yy'] - mask
更“正确”的方法是仅在蒙版位置减去。这取决于布尔数组可以用作列中的逻辑索引或掩码:
df['yy2'] = df['yy']
df.loc[mask, 'yy2'] -= 1
获取df['yy2']
之类的列会创建一个副本,如果修改了该副本,则不必写回原始数据帧。 df.loc[:, 'yy2']
是原始列的视图,用于传输更改。