计算首次出现和个体出现之间的差异 (Python Pandas)
Calculating difference between first and individual occurence (Python Pandas)
让我们以一个简单的 HR 数据框为例:
Name
Year
Department
Salary
New column: hit100after
John
2018
R&D
80
0
Marie
2018
Legal
90
0
Jill
2018
Legal
100
0
John
2019
R&D
85
0
Marie
2019
Legal
95
0
Jill
2019
Legal
105
1
John
2020
R&D
90
0
Marie
2020
Legal
100
2
Jill
2020
Legal
110
2
问题:在同一部门的第一个人达到薪水>=100之后,任何数据集花费了多少时间(以年为单位)? (参见新专栏 'hit100after')
我实际上正在努力实施。我的步骤是按部门分组,找到第一次出现的 salary >= 100 并用新的布尔类型或第二个数据框标记那一年。然后我会计算 >= 100 的个人与其部门中第一次出现之间的差异。
知道如何为大型数据框编写代码吗?
您可以 groupby()
Department
并找到 Year.min()
其中 Salary >= 100
:
first100 = df.groupby('Department').apply(
lambda g: g[g.Salary >= 100].Year.min())
# Department
# Legal 2018.0
# R&D NaN
# dtype: float64
然后 map()
first100
年 Department
并从 Year
中减去。结果在Result
中进行比较:
df['Result'] = df.Year - df.Department.map(first100)
df.loc[df.Salary < 100, 'Result'] = 0
# Name Year Department Salary Hit100after Result
# 0 John 2018 R&D 80 0 0.0
# 1 Marie 2018 Legal 90 0 0.0
# 2 Jill 2018 Legal 100 0 0.0
# 3 John 2019 R&D 85 0 0.0
# 4 Marie 2019 Legal 95 0 0.0
# 5 Jill 2019 Legal 105 1 1.0
# 6 John 2020 R&D 90 0 0.0
# 7 Marie 2020 Legal 100 2 2.0
# 8 Jill 2020 Legal 110 2 2.0
当前答案的时间安排
method
%timeit
with 1 million rows
this answer
3.07 ms ± 23.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
query()
answer
4.33 ms ± 354 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
你可以试试:
new_col = (df.query("Salary >= 100")
.groupby("Department")
.apply(lambda x: x.Year - x.iloc[0].Year)
.reset_index(level=0, drop=True)
.T)
df["hit100after"] = new_col
df["hit100after"] = df["hit100after"].fillna(0).astype(int)
首先我们查看薪水大于 100 的条目 (query
),然后按部门对它们进行分组 (groupby
),应用一个函数来获取相对于部门中的第一个条目(apply
和 iloc[0]
),删除部门名称(reset_index
在第 0 级,drop
为 True
)并取一个转置 (T
) 以确保它是垂直的,以便于与原始 df
.
对齐
最后,我们将这个新列分配给 df
,但由于我们只选择了带有 Salary >= 100
的列,因此在分配时有 NaN
;因此 fillna(0)
。由于 NaN
在技术上是一个浮点数,它使系列浮动,所以我们最后转换为 int
。
获得:
Name Year Department Salary hit100after
0 John 2018 R&D 80 0
1 Marie 2018 Legal 90 0
2 Jill 2018 Legal 100 0
3 John 2019 R&D 85 0
4 Marie 2019 Legal 95 0
5 Jill 2019 Legal 105 1
6 John 2020 R&D 90 0
7 Marie 2020 Legal 100 2
8 Jill 2020 Legal 110 2
让我们以一个简单的 HR 数据框为例:
Name | Year | Department | Salary | New column: hit100after |
---|---|---|---|---|
John | 2018 | R&D | 80 | 0 |
Marie | 2018 | Legal | 90 | 0 |
Jill | 2018 | Legal | 100 | 0 |
John | 2019 | R&D | 85 | 0 |
Marie | 2019 | Legal | 95 | 0 |
Jill | 2019 | Legal | 105 | 1 |
John | 2020 | R&D | 90 | 0 |
Marie | 2020 | Legal | 100 | 2 |
Jill | 2020 | Legal | 110 | 2 |
问题:在同一部门的第一个人达到薪水>=100之后,任何数据集花费了多少时间(以年为单位)? (参见新专栏 'hit100after')
我实际上正在努力实施。我的步骤是按部门分组,找到第一次出现的 salary >= 100 并用新的布尔类型或第二个数据框标记那一年。然后我会计算 >= 100 的个人与其部门中第一次出现之间的差异。
知道如何为大型数据框编写代码吗?
您可以 groupby()
Department
并找到 Year.min()
其中 Salary >= 100
:
first100 = df.groupby('Department').apply(
lambda g: g[g.Salary >= 100].Year.min())
# Department
# Legal 2018.0
# R&D NaN
# dtype: float64
然后 map()
first100
年 Department
并从 Year
中减去。结果在Result
中进行比较:
df['Result'] = df.Year - df.Department.map(first100)
df.loc[df.Salary < 100, 'Result'] = 0
# Name Year Department Salary Hit100after Result
# 0 John 2018 R&D 80 0 0.0
# 1 Marie 2018 Legal 90 0 0.0
# 2 Jill 2018 Legal 100 0 0.0
# 3 John 2019 R&D 85 0 0.0
# 4 Marie 2019 Legal 95 0 0.0
# 5 Jill 2019 Legal 105 1 1.0
# 6 John 2020 R&D 90 0 0.0
# 7 Marie 2020 Legal 100 2 2.0
# 8 Jill 2020 Legal 110 2 2.0
当前答案的时间安排
method | %timeit with 1 million rows |
---|---|
this answer | 3.07 ms ± 23.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) |
query() answer |
4.33 ms ± 354 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) |
你可以试试:
new_col = (df.query("Salary >= 100")
.groupby("Department")
.apply(lambda x: x.Year - x.iloc[0].Year)
.reset_index(level=0, drop=True)
.T)
df["hit100after"] = new_col
df["hit100after"] = df["hit100after"].fillna(0).astype(int)
首先我们查看薪水大于 100 的条目 (query
),然后按部门对它们进行分组 (groupby
),应用一个函数来获取相对于部门中的第一个条目(apply
和 iloc[0]
),删除部门名称(reset_index
在第 0 级,drop
为 True
)并取一个转置 (T
) 以确保它是垂直的,以便于与原始 df
.
最后,我们将这个新列分配给 df
,但由于我们只选择了带有 Salary >= 100
的列,因此在分配时有 NaN
;因此 fillna(0)
。由于 NaN
在技术上是一个浮点数,它使系列浮动,所以我们最后转换为 int
。
获得:
Name Year Department Salary hit100after
0 John 2018 R&D 80 0
1 Marie 2018 Legal 90 0
2 Jill 2018 Legal 100 0
3 John 2019 R&D 85 0
4 Marie 2019 Legal 95 0
5 Jill 2019 Legal 105 1
6 John 2020 R&D 90 0
7 Marie 2020 Legal 100 2
8 Jill 2020 Legal 110 2