【问题标题】:Pandas: Is there any way to add specific columns in dataframe based on conditional matchPandas:有没有办法根据条件匹配在数据框中添加特定列
【发布时间】:2023-03-24 23:00:01
【问题描述】:

我有从一月到十二月的列,根据当前月份,我必须得到月份的总和。例如:如果当前月份是四月,我的代码应该添加从一月到四月的所有列并忽略所有其他列。

原表:

| Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |   |
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|---|
| 2   | 3   | 4   | 5   | 6   | 7   | 8   | 9   | 12  | 1   | 3   | 5   |   |
| 1   | 23  | 4   | 5   | 76  | 7   | 423 | 57  | 689 | 345 | 23  | 2   |   |

我有过去 3 年包含多个列的庞大数据集,比如 2015 年、2016 年、2017 年。每年我都有如下列: Jan'、'Feb'、'Mar' 等等。

我需要分别获取每一年每一列的总和。所以我列了清单,然后我把它们加起来。但是这种方法太冗长了。

我还尝试将其他列(在此示例中为 5 月至 12 月)中的值设置为零,以便仅添加 1 月至 4 月。这种方法也行得通,但它涉及大量代码,并且在将来需要进行任何新修改时存在太多手动错误的空间。


list_2015 = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']

df1['2015_Dec_YTD'] = df1.loc[:,list_2015].sum(axis=1)

如果我以这种方式创建,它可以正常工作,但是代码会变得太长,因为每个月我都必须创建一个单独的列表,以便添加这些列。

我正在寻找一种更简单的方法来在数据框中有条件地添加列以创建新列。基本工作流程将是: 如果 current_month = 四月,那么(到当前月份的总和)=(一月+二月+三月+四月)

预期输出:

| Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |  SUM till current month |
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-------------------------|
| 2   | 3   | 4   | 5   | 6   | 7   | 8   | 9   | 12  | 1   | 3   | 5   | 14                      |
| 1   | 23  | 4   | 5   | 76  | 7   | 423 | 57  | 689 | 345 | 23  | 2   | 33                      |

【问题讨论】:

    标签: python pandas dataframe multiple-columns


    【解决方案1】:

    如果您想要“if current_month = April...”之类的内容,您可以使用 get_lociloc

    df.iloc[:,:df.columns.get_loc("Apr")+1].sum(axis=1)
    
    #
    0    14
    1    33
    dtype: int64
    

    【讨论】:

      【解决方案2】:

      根据current_month按列执行Boolean indexing

      current_month='Apr'
      current_mask=pd.Series(df.columns.str.contains(current_month)).shift(fill_value=False).cumsum().eq(0)
      print(current_mask)
      

      0      True
      1      True
      2      True
      3      True
      4     False
      5     False
      6     False
      7     False
      8     False
      9     False
      10    False
      11    False
      dtype: bool
      

      df['SUM till current month']=df[df.columns[current_mask]].sum(axis=1)
      print(df)
      

         Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec  \
      0    2    3    4    5    6    7    8    9   12    1    3    5   
      1    1   23    4    5   76    7  423   57  689  345   23    2   
      
         SUM till current month  
      0                      14  
      1                      33  
      

      详情:

      Series.str.contains 用于定位我们想要获得总和的月份。 所以目标是在这个专栏和之前的专栏中得到一个带有True的掩码

      current_month='Apr'
      df.columns.str.contains(current_month)
      
      array([False, False, False,  True, False, False, False, False, False,
             False, False, False])
      

      为此,我们使用Series.shift + Series.cumsum 来区分这些列:

      pd.Series(df.columns.str.contains(current_month)).shift(fill_value=False)
      0     False
      1     False
      2     False
      3     False
      4      True
      5     False
      6     False
      7     False
      8     False
      9     False
      10    False
      11    False
      dtype: bool
      

      pd.Series(df.columns.str.contains(current_month)).shift(fill_value=False).cumsum()
      
      0     0
      1     0
      2     0
      3     0
      4     1
      5     1
      6     1
      7     1
      8     1
      9     1
      10    1
      11    1
      dtype: int64
      

      现在我们通过使用Series.eq 选择它们来创建掩码

      pd.Series(df.columns.str.contains(current_month)).shift(fill_value=False).cumsum().eq(0)
      
      
      0      True
      1      True
      2      True
      3      True
      4     False
      5     False
      6     False
      7     False
      8     False
      9     False
      10    False
      11    False
      dtype: bool
      

      【讨论】:

      • 谢谢,但月份变量将每 30 天更改一次。我正在尝试获得一个足够健壮的代码,只要变量“月”发生变化,它就可以工作,它应该能够提供更新的输出,而无需对代码进行任何更改。
      • 我已经更新了解决方案,使其成为current_month的函数。现在检查
      • 效果很好。非常感谢。欣赏你的努力。您能否提供任何具体细节,这究竟是如何工作的? current_mask=pd.Series(df.columns.str.contains(current_month)).shift(fill_value=False).cumsum().eq(0)
      • 很高兴为您提供帮助,我已经添加了如何逐步获取布尔索引系列的详细信息。
      猜你喜欢
      • 2020-08-05
      • 2021-07-22
      • 1970-01-01
      • 2021-03-02
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      相关资源
      最近更新 更多