【问题标题】:Group columns based on the headers if they are found in the same list. Pandas Python如果在同一列表中找到它们,则根据标题对列进行分组。熊猫蟒
【发布时间】:2020-11-01 10:47:57
【问题描述】:

所以我有一个类似这样的数据框

Resource    2020-06-01     2020-06-02     2020-06-03
Name1            8               7              8    
Name2            7               9              9 
Name3            10              10             10

假设标题在一个月的所有日子里都是字面意思。而且名字远不止三个。

我需要将列减少到五个。考虑到第一列是2020-06-012020-06-05 之间的天数。然后从同一周的周六到周五。如果在星期五之前,则为该月的最后一天。所以六月将是这几周:

week 1: 2020-06-01 to 2020-06-05
week 2: 2020-06-06 to 2020-06-12
week 3: 2020-06-13 to 2020-06-19
week 4: 2020-06-20 to 2020-06-26
week 5: 2020-06-27 to 2020-06-30

定义这几周没有问题。问题是根据它们对列进行分组。 我什么都想不出来。

有人对此有任何想法吗?

【问题讨论】:

    标签: python pandas datetime group-by pandas-groupby


    【解决方案1】:

    我必须使用这些代码来生成您的数据框。

    dates = pd.date_range(start='2020-06-01', end='2020-06-30')
    df = pd.DataFrame({
        'Name1': np.random.randint(1, 10, size=len(dates)),
        'Name2': np.random.randint(1, 10, size=len(dates)),
        'Name3': np.random.randint(1, 10, size=len(dates)),
    })
    df = df.set_index(dates).transpose().reset_index().rename(columns={'index': 'Resource'})
    

    那么,解决办法从这里开始。

    # Set the first column as index
    df = df.set_index(df['Resource'])
    
    # Remove the unused column
    df = df.drop(columns=['Resource'])
    
    # Transpose the dataframe
    df = df.transpose()
    
    # Output:
    Resource    Name1   Name2   Name3
    2020-06-01 00:00:00 3   2   7
    2020-06-02 00:00:00 5   6   8
    2020-06-03 00:00:00 2   3   6
    ...
    
    # Bring "Resource" from index to column
    df = df.reset_index()
    df = df.rename(columns={'index': 'Resource'})
    
    # Add a column "week of year"
    df['week_no'] = df['Resource'].dt.weekofyear
    
    # You can simply group by the week no column
    df.groupby('week_no').sum().reset_index()
    
    # Output:
    Resource    week_no Name1   Name2   Name3
    0   23  38  42  41
    1   24  37  30  43
    2   25  38  29  23
    3   26  29  40  42
    4   27  2   8   3
    

    我不知道你接下来想做什么。如果您想要原始表单,只需transpose() 将其返回即可。

    编辑:OP 声称这周应该从星期六开始,到星期五结束

    # 0: Monday
    # 1: Tuesday
    # 2: Wednesday
    # 3: Thursday
    # 4: Friday
    # 5: Saturday
    # 6: Sunday
    df['weekday'] = df['Resource'].dt.weekday.apply(lambda day: 0 if day <= 4 else 1)
    df['customised_weekno'] = df['week_no'] + df['weekday']
    

    输出:

    Resource    Resource    Name1   Name2   Name3   week_no weekday customised_weekno
    0   2020-06-01  4   7   7   23  0   23
    1   2020-06-02  8   6   7   23  0   23
    2   2020-06-03  5   9   5   23  0   23
    3   2020-06-04  7   6   5   23  0   23
    4   2020-06-05  6   3   7   23  0   23
    5   2020-06-06  3   7   6   23  1   24
    6   2020-06-07  5   4   4   23  1   24
    7   2020-06-08  8   1   5   24  0   24
    8   2020-06-09  2   7   9   24  0   24
    9   2020-06-10  4   2   7   24  0   24
    10  2020-06-11  6   4   4   24  0   24
    11  2020-06-12  9   5   7   24  0   24
    12  2020-06-13  2   4   6   24  1   25
    13  2020-06-14  6   7   5   24  1   25
    14  2020-06-15  8   7   7   25  0   25
    15  2020-06-16  4   3   3   25  0   25
    16  2020-06-17  6   4   5   25  0   25
    17  2020-06-18  6   8   2   25  0   25
    18  2020-06-19  3   1   2   25  0   25
    

    因此,您可以使用customised_weekno 进行分组。

    【讨论】:

    • 谢谢,我试过了,可以了。只有一件事,这要数周。所以第 23 周从 2020-06-01 到 2020-06-07,而它应该从 2020-06-01 到 2020-06-05。因为在我的场景中,所有星期都在星期五结束,或者如果不是星期五,则在该月的最后一天结束。并且总是从星期六开始,除了当月的第 1 天,它从任何时候开始就开始。但是谢谢,这是一个重要的里程碑,以便弄清楚该做什么
    • @BrunoSapia,我已根据您的要求编辑了我的答案。如果有任何误解,请告诉我。否则,请接受我的回答,以便我们关闭此问题。
    • 非常感谢。我使用了您原来的方式并对其进行了一些更改以便也可以工作 dfinal = dfinal.set_index(dfinal['Alias']) dfinal = dfinal.drop(columns=['Alias']) dfinal=dfinal.transpose( ) dfinal = dfinal.reset_index() dfinal = dfinal.rename(columns={'index': 'Alias'}) dfinal['week_no'] = dfinal['Work Date'].dt.weekofyear.shift(-2) .ffill() dfinal=dfinal.groupby(["week_no"]).sum()
    • @BrunoSapia,如果我的回答达到了你的预期,你能接受吗?
    猜你喜欢
    • 2019-01-29
    • 2013-07-30
    • 2020-11-27
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    相关资源
    最近更新 更多