如果月份=十月,十一月或十二月,则从年份减去-1,其他年份为python

时间:2018-04-10 17:25:59

标签: python pandas

我试图从我的数据框中的'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

3 个答案:

答案 0 :(得分:2)

使用Series.where

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']是原始列的视图,用于传输更改。