【问题标题】:Subtract -1 from Year if month = October, November, or December, Else year python如果月份 = 10 月、11 月或 12 月,则从年份中减去 -1,否则为 python
【发布时间】:2018-04-11 01:57:42
【问题描述】:

如果该行的“月”列中的月份 ==“十月”、“十一月”、“十二月”,我正在尝试从数据框中的“年年”列中减去 (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

【问题讨论】:

  • 这个循环不断地重新计算yy2 作为整个列,最后一项恰好是October,所以这就是你所看到的。你为什么感到惊讶?
  • 不要使用循环。
  • 您是否考虑过使用日期时间对象而不是日期的字符串表示形式?
  • @dawg。一个好主意,但与这里的问题完全无关

标签: python pandas


【解决方案1】:

使用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

【讨论】:

    【解决方案2】:

    pandas 的第一条规则:如果你在行上循环,那么你做错了。

    你想做的是使用apply:

    df['yy2'] = df.apply(lambda x: x['yy'] - 1 if x['Month'] in ['October', 'November', 'December'] else x['yy'], axis=1)
    

    【讨论】:

    • apply 也循环遍历数据。这可以完全矢量化完成
    【解决方案3】:

    通常,您不应该在 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'] 是原始列的视图,将传输更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      相关资源
      最近更新 更多