如何将Pandas Dataframe中的Non-Monday列转换为Monday

huangapple go评论68阅读模式
英文:

How to convert the Non-Monday column to Monday in Pandas Dataframe

问题

我想编写一个函数,如果日期是星期二、星期三或星期四,则将其转换为本周的星期一;如果日期是星期五、星期六或星期日,则将其转换为下周的星期一。如果日期是星期一,则保持不变。

示例输入数据框如下:

Model# Order Category 2022/4/18 2022/5/10 2022/5/18 2022/5/26 2022/6/24 2022/7/16 2022/7/24
A Open 0 0 0 0 1 1 2
B Close 1 1 0 0 1 2 2
C Open 0 0 1 1 0 1 2

理想的输出如下:

根据我指定的规则,所有日期标头都转换为星期一。

Model# Order Category 2022/4/18 2022/5/9 2022/5/16 2022/5/23 2022/6/27 2022/7/18 2022/7/25
A Open 0 0 0 0 1 1 2
B Close 1 1 0 0 1 2 2
C Open 0 0 1 1 0 1 2

非常感谢您的帮助!

英文:

I want to write a function that if a date is Tue.Wed.Tur. then convert it as this week's Monday, if a date is Fri. Sat. Sun. then convert it as next week's Monday. If its a Monday, just leave as it is.

The example input Dataframe is like this:

Model# Order Category 2022/4/18 2022/5/10 2022/5/18 2022/5/26 2022/6/24 2022/7/16 2022/7/24
A Open 0 0 0 0 1 1 2
B Close 1 1 0 0 1 2 2
C Open 0 0 1 1 0 1 2

The ideal output is like this:

All the date headers are converted to Monday based on the rules I specified.

Model# Order Category 2022/4/18 2022/5/9 2022/5/16 2022/5/23 2022/6/27 2022/7/18 2022/7/25
A Open 0 0 0 0 1 1 2
B Close 1 1 0 0 1 2 2
C Open 0 0 1 1 0 1 2

Really appreciate your help!

答案1

得分: 1

import pandas as pd
data1 = {'Model#': {0: 'A', 1: 'B', 2: 'C'},
 'Order Category': {0: 'Open', 1: 'Close', 2: 'Open'},
 '2022/4/18': {0: 0, 1: 1, 2: 0},
 '2022/5/10': {0: 0, 1: 1, 2: 0},
 '2022/5/18': {0: 0, 1: 0, 2: 1},
 '2022/5/26': {0: 0, 1: 0, 2: 1},
 '2022/6/24': {0: 1, 1: 1, 2: 0},
 '2022/7/16': {0: 1, 1: 2, 2: 1},
 '2022/7/24': {0: 2, 1: 2, 2: 2}}
df1 = pd.DataFrame(data1)

idx = pd.to_datetime(df1.columns[2:], errors='coerce').to_period('W').to_timestamp()

idx

DatetimeIndex(['2022-04-18', '2022-05-09', '2022-05-16', '2022-05-23',
               '2022-06-20', '2022-07-11', '2022-07-18'],
              dtype='datetime64[ns]', freq=None)

(df1
 .set_index(['Model#', 'Order Category'])
 .set_axis(idx.astype('str'), axis=1)
 .reset_index())

Output:

   Model# Order Category  2022-04-18  2022-05-09  2022-05-16  2022-05-23  2022-06-20  2022-07-11  2022-07-18
0      A           Open           0           0           0           0           1           1           2
1      B          Close           1           1           0           0           1           2           2
2      C           Open           0           0           1           1           0           1           2
英文:

Example

import pandas as pd
data1 = {'Model#': {0: 'A', 1: 'B', 2: 'C'},
 'Order Category': {0: 'Open', 1: 'Close', 2: 'Open'},
 '2022/4/18': {0: 0, 1: 1, 2: 0},
 '2022/5/10': {0: 0, 1: 1, 2: 0},
 '2022/5/18': {0: 0, 1: 0, 2: 1},
 '2022/5/26': {0: 0, 1: 0, 2: 1},
 '2022/6/24': {0: 1, 1: 1, 2: 0},
 '2022/7/16': {0: 1, 1: 2, 2: 1},
 '2022/7/24': {0: 2, 1: 2, 2: 2}}
df1 = pd.DataFrame(data1)

Step1

Create data only for the date part by changing the date part to monday

idx = pd.to_datetime(df1.columns[2:], errors='coerce').to_period('W').to_timestamp()

idx

DatetimeIndex(['2022-04-18', '2022-05-09', '2022-05-16', '2022-05-23',
               '2022-06-20', '2022-07-11', '2022-07-18'],
              dtype='datetime64[ns]', freq=None)

Step2

make monday index

(df1
 .set_index(['Model#', 'Order Category'])
 .set_axis(idx.astype('str'), axis=1)
 .reset_index())

output:

Model#	Order Category	2022-04-18	2022-05-09	2022-05-16	2022-05-23	2022-06-20	2022-07-11	2022-07-18
0	A	Open	        0	        0	        0	        0	        1	        1	        2
1	B	Close	        1	        1	        0	        0	        1	        2	        2
2	C	Open	        0	        0	        1	        1	        0	        1	        2

答案2

得分: 1

你可以使用以下代码:

import numpy as np

# 将列转换为日期并提取星期几
dates = pd.to_datetime(df.columns[2:])
dow = dates.day_of_week

# 创建时间差,星期一至星期四为负数,星期五至星期日为正数
offsets = pd.to_timedelta(np.where(dow < 4, -dow, 7-dow), unit='D')

# 调整日期,然后重新索引列
dates = (dates + offsets).strftime('%Y/%-m/%-d')
df.columns = df.columns[:2].append(dates)

输出:

Model# Order Category 2022/4/18 2022/5/9 2022/5/16 2022/5/23 2022/6/27 2022/7/18 2022/7/25
A Open 0 0 0 0 1 1 2
B Close 1 1 0 0 1 2 2
C Open 0 0 1 1 0 1 2

中间结果:

Before Offset After
2022-04-18 0 天 2022-04-18
2022-05-10 -1 天 2022-05-09
2022-05-18 -2 天 2022-05-16
2022-05-26 -3 天 2022-05-23
2022-06-24 3 天 2022-06-27
2022-07-16 2 天 2022-07-18
2022-07-24 1 天 2022-07-25

<details>
<summary>英文:</summary>

You can use:

import numpy as np

Convert as datetime and extract day of week

dates = pd.to_datetime(df.columns[2:])
dow = dates.day_of_week

Create timedelta Mon, Thu, Wed, Thu are negative, Fri, Sat, Sun are positive

offsets = pd.to_timedelta(np.where(dow < 4, -dow, 7-dow), unit='D')

Adjust the dates then reindex your columns

dates = (dates + offsets).strftime('%Y/%-m/%-d')
df.columns = df.columns[:2].append(dates)


Output:

| Model#   | Order Category   |   2022/4/18 |   2022/5/9 |   2022/5/16 |   2022/5/23 |   2022/6/27 |   2022/7/18 |   2022/7/25 |
|:---------|:-----------------|------------:|-----------:|------------:|------------:|------------:|------------:|------------:|
| A        | Open             |           0 |          0 |           0 |           0 |           1 |           1 |           2 |
| B        | Close            |           1 |          1 |           0 |           0 |           1 |           2 |           2 |
| C        | Open             |           0 |          0 |           1 |           1 |           0 |           1 |           2 |

Intermediates:

| Before     | Offset   | After      |
|:-----------|:---------|:-----------|
| 2022-04-18 | 0 days   | 2022-04-18 |
| 2022-05-10 | -1 days  | 2022-05-09 |
| 2022-05-18 | -2 days  | 2022-05-16 |
| 2022-05-26 | -3 days  | 2022-05-23 |
| 2022-06-24 | 3 days   | 2022-06-27 |
| 2022-07-16 | 2 days   | 2022-07-18 |
| 2022-07-24 | 1 days   | 2022-07-25 |


</details>



huangapple
  • 本文由 发表于 2023年6月22日 12:07:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76528548.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定