如何将三列合并为两列,一列是分类列,另一列是数字列? (python pandas)
How do I merge three columns into two, One categorical and the other numerical? (python pandas)
这里是数据科学实习生。
好的,所以我目前在 python 中有一个数据框,看起来像:
df = pd.DataFrame({'Utility': ["Akron", 'Akron', 'Akron', 'Akron'],
'Area': ['other', 'other', 'other', 'other'],
'Category': ['Digital', 'Digital', 'Digital',
'Digital'],
'Subcategory': ['Plans', 'Services', 'Asset
Management', 'Billing'],
'Unit':['USD','USD','USD','USD'],
'Value':[0,0,0,0],
"Population Served":
[280000,280000,280000,280000]})
print(df)
输出:
Utility Area Category Subcategory Unit Value Population Served
0 Akron other Digital Plans USD 0 280000
1 Akron other Digital Services USD 0 280000
2 Akron other Digital Asset Management USD 0 280000
3 Akron other Digital Billing USD 0 280000
我的主管说她需要能够过滤列单位,以便找到价值和服务人口列。因此,她希望 Unit 列包含两个类别:(服务人口和美元),而 Value 列只包含给定效用的人口或支出。注意:我猜她希望所有类别列(区域、类别、子类别等)对于指示给定公用事业服务的人口的任何行都是空白的。
所以我需要它看起来像:
df = pd.DataFrame({'Utility': ["Akron", 'Akron', 'Akron', 'Akron',
"Akron", 'Akron', 'Akron', 'Akron'],
'Area': ['other', 'other', 'other', 'other', np.nan,
np.nan, np.nan, np.nan],
'Category': ['Digital', 'Digital', 'Digital',
'Digital', np.nan, np.nan, np.nan, np.nan],
'Subcategory': ['Plans', 'Services', 'Asset
Management', 'Billing', np.nan,np.nan,np.nan,np.nan],
'Unit':['USD','USD','USD','USD', 'Pop Served', 'Pop
Served', 'Pop Served', 'Pop Served'],
'Value':[0,0,0,0,280000,280000,280000,280000]})
打印(df)
输出:
Utility Area Category Subcategory Unit Value
0 Akron other Digital Plans USD 0
1 Akron other Digital Services USD 0
2 Akron other Digital Asset Management USD 0
3 Akron other Digital Billing USD 0
4 Akron NaN NaN NaN Pop Served 280000
5 Akron NaN NaN NaN Pop Served 280000
6 Akron NaN NaN NaN Pop Served 280000
7 Akron NaN NaN NaN Pop Served 280000
我一直在尝试使用 pd.melt 来完成此操作,但我不知道该怎么做,因为我正在处理将 3 列分成两列的问题。我愿意用 for 循环来做到这一点,但我担心这可能会花费太长时间,并且在插入新行时需要精确的索引。
明确地说,我认为这不是个好主意。我认为它没有真正充分的理由使文件的大小加倍。我也将接受关于如何在 excel 内完成她想要的视图的答案,而不必玩 csv。
为了区分不同行中的值,我将源 DataFrame 定义为:
Utility Area Category Subcategory Unit Value Population Served
0 Akron other Digital Plans USD 0 280100
1 Akron other Digital Services USD 10 280200
2 Akron other Digital Asset Management USD 20 280300
3 Akron other Digital Billing USD 30 280400
要获得结果,运行 以下代码:
wrk = df.drop(columns=['Unit']).rename(columns={'Value': 'USD'})\
.set_index(df.columns[:4].to_list()).stack().rename('Value')
wrk.index.rename('Unit', level=4, inplace=True)
result = wrk.sort_index(level=4, sort_remaining=False).reset_index()
result.loc[result.Unit == 'Population Served', df.columns[1:4].to_list()] = np.nan
对于我的源数据,结果是:
Utility Area Category Subcategory Unit Value
0 Akron other Digital Plans USD 0
1 Akron other Digital Services USD 10
2 Akron other Digital Asset Management USD 20
3 Akron other Digital Billing USD 30
4 Akron NaN NaN NaN Population Served 280100
5 Akron NaN NaN NaN Population Served 280200
6 Akron NaN NaN NaN Population Served 280300
7 Akron NaN NaN NaN Population Served 280400
要完全理解上述代码的工作原理,运行 是逐步的(一种方法
一个接一个)并查看部分结果。
也许您还应该阅读有关所用方法的文档。
编辑
另一种方法是使用 melt:
result = df.drop(columns=['Unit']).rename(columns={'Value': 'USD'})\
.melt(id_vars=['Utility', 'Area', 'Category', 'Subcategory'],
value_vars=['USD', 'Population Served'], var_name='Unit',
value_name='Value')
result.loc[result.Unit == 'Population Served', df.columns[1:4].to_list()] = np.nan
这里是数据科学实习生。
好的,所以我目前在 python 中有一个数据框,看起来像:
df = pd.DataFrame({'Utility': ["Akron", 'Akron', 'Akron', 'Akron'],
'Area': ['other', 'other', 'other', 'other'],
'Category': ['Digital', 'Digital', 'Digital',
'Digital'],
'Subcategory': ['Plans', 'Services', 'Asset
Management', 'Billing'],
'Unit':['USD','USD','USD','USD'],
'Value':[0,0,0,0],
"Population Served":
[280000,280000,280000,280000]})
print(df)
输出:
Utility Area Category Subcategory Unit Value Population Served
0 Akron other Digital Plans USD 0 280000
1 Akron other Digital Services USD 0 280000
2 Akron other Digital Asset Management USD 0 280000
3 Akron other Digital Billing USD 0 280000
我的主管说她需要能够过滤列单位,以便找到价值和服务人口列。因此,她希望 Unit 列包含两个类别:(服务人口和美元),而 Value 列只包含给定效用的人口或支出。注意:我猜她希望所有类别列(区域、类别、子类别等)对于指示给定公用事业服务的人口的任何行都是空白的。
所以我需要它看起来像:
df = pd.DataFrame({'Utility': ["Akron", 'Akron', 'Akron', 'Akron',
"Akron", 'Akron', 'Akron', 'Akron'],
'Area': ['other', 'other', 'other', 'other', np.nan,
np.nan, np.nan, np.nan],
'Category': ['Digital', 'Digital', 'Digital',
'Digital', np.nan, np.nan, np.nan, np.nan],
'Subcategory': ['Plans', 'Services', 'Asset
Management', 'Billing', np.nan,np.nan,np.nan,np.nan],
'Unit':['USD','USD','USD','USD', 'Pop Served', 'Pop
Served', 'Pop Served', 'Pop Served'],
'Value':[0,0,0,0,280000,280000,280000,280000]})
打印(df)
输出:
Utility Area Category Subcategory Unit Value
0 Akron other Digital Plans USD 0
1 Akron other Digital Services USD 0
2 Akron other Digital Asset Management USD 0
3 Akron other Digital Billing USD 0
4 Akron NaN NaN NaN Pop Served 280000
5 Akron NaN NaN NaN Pop Served 280000
6 Akron NaN NaN NaN Pop Served 280000
7 Akron NaN NaN NaN Pop Served 280000
我一直在尝试使用 pd.melt 来完成此操作,但我不知道该怎么做,因为我正在处理将 3 列分成两列的问题。我愿意用 for 循环来做到这一点,但我担心这可能会花费太长时间,并且在插入新行时需要精确的索引。
明确地说,我认为这不是个好主意。我认为它没有真正充分的理由使文件的大小加倍。我也将接受关于如何在 excel 内完成她想要的视图的答案,而不必玩 csv。
为了区分不同行中的值,我将源 DataFrame 定义为:
Utility Area Category Subcategory Unit Value Population Served
0 Akron other Digital Plans USD 0 280100
1 Akron other Digital Services USD 10 280200
2 Akron other Digital Asset Management USD 20 280300
3 Akron other Digital Billing USD 30 280400
要获得结果,运行 以下代码:
wrk = df.drop(columns=['Unit']).rename(columns={'Value': 'USD'})\
.set_index(df.columns[:4].to_list()).stack().rename('Value')
wrk.index.rename('Unit', level=4, inplace=True)
result = wrk.sort_index(level=4, sort_remaining=False).reset_index()
result.loc[result.Unit == 'Population Served', df.columns[1:4].to_list()] = np.nan
对于我的源数据,结果是:
Utility Area Category Subcategory Unit Value
0 Akron other Digital Plans USD 0
1 Akron other Digital Services USD 10
2 Akron other Digital Asset Management USD 20
3 Akron other Digital Billing USD 30
4 Akron NaN NaN NaN Population Served 280100
5 Akron NaN NaN NaN Population Served 280200
6 Akron NaN NaN NaN Population Served 280300
7 Akron NaN NaN NaN Population Served 280400
要完全理解上述代码的工作原理,运行 是逐步的(一种方法 一个接一个)并查看部分结果。
也许您还应该阅读有关所用方法的文档。
编辑
另一种方法是使用 melt:
result = df.drop(columns=['Unit']).rename(columns={'Value': 'USD'})\
.melt(id_vars=['Utility', 'Area', 'Category', 'Subcategory'],
value_vars=['USD', 'Population Served'], var_name='Unit',
value_name='Value')
result.loc[result.Unit == 'Population Served', df.columns[1:4].to_list()] = np.nan