Python pandas。如果列值位于第二个数据框的另一个逗号分隔值列中,则需要聚合
Python pandas. Need to aggregate if column value is in another comma separated value column of second dataframe
我有 2 个数据框样本,名称已更改
df1 =
| Comp_code | DepartmentListA | DepartmentListB |
| -------- | --------------- | --------------- |
| Code_1 | "Dept1" | "Dept3" |
| Code_2 | "Dept2" | "Dept4" |
| Code_3 | "Dept4, Dept5" | "Dept1" |
| Code_4 | "Dept1,Dept5, Dept6" | "Dept3, Dept4" |
df2 = 只有部门和收入
| DepartmentList | Revenue| Gross Margin|
| --------------- | -------| -------|
| "Dept1" | 1000 | 500
| "Dept2" | 2000 | 0
| "Dept3, | 5000 | 900
| "Dept4" | 5000 | 200
| "Dept5" | 7000 | -100
| "Dept6" | 8000 | 2500
我希望我的最终 df 包含公司代码以及总收入和毛利率。汇总 A 列和 B 列中的部门总数。
由于以逗号分隔的部门字符串,我无法迭代和加入。我最后的DF应该是这样的
预期 df =
| Comp_code | GrossRev| Tot Margin|
| -------- | --------------- | --------------- |
| Code_1 | 6000 | 1400 |
| Code_2 | 7000 | 200 |
| Code_3 | 13000 | 600 |
| Code_4 | 26000 | 4000 |
数据框也有几百万行,一些部门列表(逗号分隔值)大约有 100 个。如果有一种高效的方法来做到这一点,那就太好了。
TIA,
您可以通过以下方式做到这一点
df["all"] = ((df["DepartmentListA"] +
", " +
df["DepartmentListB"]).str.split("[\s,]+"))
df3 = df.explode("all")
df3 = (pd.merge(df3, df2, left_on='all',
right_on='Comp_code', suffixes=('', '_y'))
.groupby("Comp_code")
.agg({'Revenue': ['sum'], 'Gross Margin': 'sum'}).reset_index())
df3.columns = df3.columns.droplevel(-1)
print(df3)
Comp_code Revenue Gross Margin
0 Code_1 6000 1400
1 Code_2 7000 200
2 Code_3 13000 600
3 Code_4 26000 4000
您可以 melt
+explode
获取每个部门的单独行,然后 merge
和 df2
获取数据,最后 groupby
+ sum
聚合 sum
:
(df1.melt(id_vars='Comp_code')
.assign(value=lambda d: d['value'].str.split(r',\s*'))
.explode('value')
.merge(df2, left_on='value', right_on='DepartmentList')
.groupby('Comp_code').agg({'Revenue': 'sum', 'Gross Margin': 'sum'})
)
输出:
Revenue Gross Margin
Comp_code
Code_1 6000 1400
Code_2 7000 200
Code_3 13000 600
Code_4 26000 4000
我有 2 个数据框样本,名称已更改
df1 =
| Comp_code | DepartmentListA | DepartmentListB |
| -------- | --------------- | --------------- |
| Code_1 | "Dept1" | "Dept3" |
| Code_2 | "Dept2" | "Dept4" |
| Code_3 | "Dept4, Dept5" | "Dept1" |
| Code_4 | "Dept1,Dept5, Dept6" | "Dept3, Dept4" |
df2 = 只有部门和收入
| DepartmentList | Revenue| Gross Margin|
| --------------- | -------| -------|
| "Dept1" | 1000 | 500
| "Dept2" | 2000 | 0
| "Dept3, | 5000 | 900
| "Dept4" | 5000 | 200
| "Dept5" | 7000 | -100
| "Dept6" | 8000 | 2500
我希望我的最终 df 包含公司代码以及总收入和毛利率。汇总 A 列和 B 列中的部门总数。 由于以逗号分隔的部门字符串,我无法迭代和加入。我最后的DF应该是这样的
预期 df =
| Comp_code | GrossRev| Tot Margin|
| -------- | --------------- | --------------- |
| Code_1 | 6000 | 1400 |
| Code_2 | 7000 | 200 |
| Code_3 | 13000 | 600 |
| Code_4 | 26000 | 4000 |
数据框也有几百万行,一些部门列表(逗号分隔值)大约有 100 个。如果有一种高效的方法来做到这一点,那就太好了。
TIA,
您可以通过以下方式做到这一点
df["all"] = ((df["DepartmentListA"] +
", " +
df["DepartmentListB"]).str.split("[\s,]+"))
df3 = df.explode("all")
df3 = (pd.merge(df3, df2, left_on='all',
right_on='Comp_code', suffixes=('', '_y'))
.groupby("Comp_code")
.agg({'Revenue': ['sum'], 'Gross Margin': 'sum'}).reset_index())
df3.columns = df3.columns.droplevel(-1)
print(df3)
Comp_code Revenue Gross Margin
0 Code_1 6000 1400
1 Code_2 7000 200
2 Code_3 13000 600
3 Code_4 26000 4000
您可以 melt
+explode
获取每个部门的单独行,然后 merge
和 df2
获取数据,最后 groupby
+ sum
聚合 sum
:
(df1.melt(id_vars='Comp_code')
.assign(value=lambda d: d['value'].str.split(r',\s*'))
.explode('value')
.merge(df2, left_on='value', right_on='DepartmentList')
.groupby('Comp_code').agg({'Revenue': 'sum', 'Gross Margin': 'sum'})
)
输出:
Revenue Gross Margin
Comp_code
Code_1 6000 1400
Code_2 7000 200
Code_3 13000 600
Code_4 26000 4000