如何将多个列转换为 pandas 中的单个 rows/values?
How do I convert multiple columns to individual rows/values in pandas?
我确信这个问题已经得到解答,但不幸的是我不知道如何称呼这个操作,所以我的搜索失败了。它几乎就像一个反向枢轴 table.
假设我有以下工资单数据:
data = [
{'employee': 1, 'date': '2020-01-04', 'reg': 8, 'ot': 0, 'dt': 0},
{'employee': 1, 'date': '2020-01-05', 'reg': 4, 'ot': 4, 'dt': 0},
{'employee': 1, 'date': '2020-01-06', 'reg': 0, 'ot': 0, 'dt': 4},
{'employee': 2, 'date': '2020-01-04', 'reg': 6, 'ot': 2, 'dt': 0},
{'employee': 2, 'date': '2020-01-05', 'reg': 3, 'ot': 5, 'dt': 0},
{'employee': 2, 'date': '2020-01-06', 'reg': 0, 'ot': 4, 'dt': 0},
]
data_df = pd.DataFrame(data)
我需要做的是将每个 employee/date 的每个比率('reg'、'ot' 和 'dt')分解到它自己的行中费率标签列和小时数列,保留其他非基于费率的列。此外,我不希望任何值为零的费率出现一行。对于上面的数据,我希望获得:
result = [
{'employee': 1, 'date': '2020-01-04', 'rate': 'reg', 'hours': 8},
{'employee': 1, 'date': '2020-01-05', 'rate': 'reg', 'hours': 4},
{'employee': 1, 'date': '2020-01-05', 'rate': 'ot', 'hours': 4},
{'employee': 1, 'date': '2020-01-06', 'rate': 'dt', 'hours': 4},
{'employee': 2, 'date': '2020-01-04', 'rate': 'reg', 'hours': 6},
{'employee': 2, 'date': '2020-01-04', 'rate': 'ot', 'hours': 2},
{'employee': 2, 'date': '2020-01-05', 'rate': 'reg', 'hours': 3},
{'employee': 2, 'date': '2020-01-05', 'rate': 'ot', 'hours': 5},
{'employee': 2, 'date': '2020-01-06', 'rate': 'ot', 'hours': 4},
]
result_df = pd.DataFrame(result)
如有任何关于如何实现此目的的想法,我们将不胜感激!
尝试使用 melt
:
(data_df.melt(['employee','date'],
var_name='rate',
value_name='hours')
.query('hours != 0'))
输出:
employee date rate hours
0 1 2020-01-04 reg 8
1 1 2020-01-05 reg 4
3 2 2020-01-04 reg 6
4 2 2020-01-05 reg 3
7 1 2020-01-05 ot 4
9 2 2020-01-04 ot 2
10 2 2020-01-05 ot 5
11 2 2020-01-06 ot 4
14 1 2020-01-06 dt 4
这应该可以解决问题:
data_df=data_df.set_index(["employee", "date"]).stack().reset_index().rename(columns={"level_2": "rate", 0: "hours"})
输出:
employee date rate hours
0 1 2020-01-04 reg 8
1 1 2020-01-04 ot 0
2 1 2020-01-04 dt 0
3 1 2020-01-05 reg 4
4 1 2020-01-05 ot 4
5 1 2020-01-05 dt 0
6 1 2020-01-06 reg 0
7 1 2020-01-06 ot 0
8 1 2020-01-06 dt 4
9 2 2020-01-04 reg 6
10 2 2020-01-04 ot 2
11 2 2020-01-04 dt 0
12 2 2020-01-05 reg 3
13 2 2020-01-05 ot 5
14 2 2020-01-05 dt 0
15 2 2020-01-06 reg 0
16 2 2020-01-06 ot 4
17 2 2020-01-06 dt 0
我确信这个问题已经得到解答,但不幸的是我不知道如何称呼这个操作,所以我的搜索失败了。它几乎就像一个反向枢轴 table.
假设我有以下工资单数据:
data = [
{'employee': 1, 'date': '2020-01-04', 'reg': 8, 'ot': 0, 'dt': 0},
{'employee': 1, 'date': '2020-01-05', 'reg': 4, 'ot': 4, 'dt': 0},
{'employee': 1, 'date': '2020-01-06', 'reg': 0, 'ot': 0, 'dt': 4},
{'employee': 2, 'date': '2020-01-04', 'reg': 6, 'ot': 2, 'dt': 0},
{'employee': 2, 'date': '2020-01-05', 'reg': 3, 'ot': 5, 'dt': 0},
{'employee': 2, 'date': '2020-01-06', 'reg': 0, 'ot': 4, 'dt': 0},
]
data_df = pd.DataFrame(data)
我需要做的是将每个 employee/date 的每个比率('reg'、'ot' 和 'dt')分解到它自己的行中费率标签列和小时数列,保留其他非基于费率的列。此外,我不希望任何值为零的费率出现一行。对于上面的数据,我希望获得:
result = [
{'employee': 1, 'date': '2020-01-04', 'rate': 'reg', 'hours': 8},
{'employee': 1, 'date': '2020-01-05', 'rate': 'reg', 'hours': 4},
{'employee': 1, 'date': '2020-01-05', 'rate': 'ot', 'hours': 4},
{'employee': 1, 'date': '2020-01-06', 'rate': 'dt', 'hours': 4},
{'employee': 2, 'date': '2020-01-04', 'rate': 'reg', 'hours': 6},
{'employee': 2, 'date': '2020-01-04', 'rate': 'ot', 'hours': 2},
{'employee': 2, 'date': '2020-01-05', 'rate': 'reg', 'hours': 3},
{'employee': 2, 'date': '2020-01-05', 'rate': 'ot', 'hours': 5},
{'employee': 2, 'date': '2020-01-06', 'rate': 'ot', 'hours': 4},
]
result_df = pd.DataFrame(result)
如有任何关于如何实现此目的的想法,我们将不胜感激!
尝试使用 melt
:
(data_df.melt(['employee','date'],
var_name='rate',
value_name='hours')
.query('hours != 0'))
输出:
employee date rate hours
0 1 2020-01-04 reg 8
1 1 2020-01-05 reg 4
3 2 2020-01-04 reg 6
4 2 2020-01-05 reg 3
7 1 2020-01-05 ot 4
9 2 2020-01-04 ot 2
10 2 2020-01-05 ot 5
11 2 2020-01-06 ot 4
14 1 2020-01-06 dt 4
这应该可以解决问题:
data_df=data_df.set_index(["employee", "date"]).stack().reset_index().rename(columns={"level_2": "rate", 0: "hours"})
输出:
employee date rate hours
0 1 2020-01-04 reg 8
1 1 2020-01-04 ot 0
2 1 2020-01-04 dt 0
3 1 2020-01-05 reg 4
4 1 2020-01-05 ot 4
5 1 2020-01-05 dt 0
6 1 2020-01-06 reg 0
7 1 2020-01-06 ot 0
8 1 2020-01-06 dt 4
9 2 2020-01-04 reg 6
10 2 2020-01-04 ot 2
11 2 2020-01-04 dt 0
12 2 2020-01-05 reg 3
13 2 2020-01-05 ot 5
14 2 2020-01-05 dt 0
15 2 2020-01-06 reg 0
16 2 2020-01-06 ot 4
17 2 2020-01-06 dt 0