python - 如何处理 ValueError:索引包含使用 df.pivot 或 pd.pivot_table 的重复条目?
问题描述
我有一张表格,显示了dataframe values
不同专家 ( ID
) 完成一系列四项任务所花费的累计小时数 ( ),['Task1, 'Tas2', 'Task3, 'Tas4']
如下所示:
输入:
ID Task1 Task2 Task3 Task4
0 10 1 3 4 6
1 11 1 3 4 5
2 12 1 3 4 6
现在我想重塑那个数据框,以便我可以轻松地找出每个专家在 1 小时、2 小时等后正在处理的任务。所以所需的输出如下所示:
期望的输出:
value 1 3 4 5 6
ID
10 Task1 Task2 Task3 Task3 Task4
11 Task1 Task2 Task3 Task4 Task4
12 Task1 Task2 Task3 Task3 Task4
使用这个特定的数据框,我已经设法使用 , 生成所需的输出pd.melt()
,pd.pivot()
并且pd.fillna()
像这样(完整的片段和示例数据进一步向下):
我试过的:
df = pd.melt(df1, id_vars=['ID'], value_vars=df1.columns[1:])
df = df.pivot(index='ID', columns = 'value', values = 'variable')
df = df.fillna(method = 'ffill', axis = 1)
问题是这种方法不是很健壮,因为它很容易与会呈现(我认为)重复列名的数据集崩溃。这是一个示例,仅通过更改Task3
for ID=0
from就会发生这种情况5 to 4
:
代码 1
import pandas as pd
df1 = pd.DataFrame({ 'ID': {0: 10, 1: 11, 2: 12},
'Task1': {0: 1, 1: 1, 2: 1},
'Task2': {0: 4, 1: 3, 2: 3},
'Task3': {0: 4, 1: 4, 2: 4},
'Task4': {0: 6, 1: 5, 2: 6}})
df = pd.melt(df1, id_vars=['ID'], value_vars=df1.columns[1:])
df = df.pivot(index='ID', columns = 'value', values = 'variable')
df = df.fillna(method = 'ffill', axis = 1)
df
代码 1 - 错误:
ValueError:索引包含重复的条目,无法重塑
根据文档,pd.pivot_table()是:
可以处理一个索引/列对的重复值的枢轴的泛化。
所以我希望这pd.pivot_table()
会更适合这种情况。唉,这会触发:
DataError:没有要聚合的数字类型
有谁知道是否有可能获得处理这些错误的可靠方法?我可能只是使用pd.pivot_table()
了错误的方式吗?我也尝试过包括aggfunc=None
.
我在这里不知所措,所以任何建议都会很棒!尽管我希望采用df.pivot
orpd.pivot_table
和/或尽可能最短的方法。
完整的工作代码示例:
import pandas as pd
df1 = pd.DataFrame({ 'ID': {0: 10, 1: 11, 2: 12},
'Task1': {0: 1, 1: 1, 2: 1},
'Task2': {0: 4, 1: 3, 2: 3},
'Task3': {0: 5, 1: 4, 2: 4},
'Task4': {0: 6, 1: 5, 2: 6}})
df = pd.melt(df1, id_vars=['ID'], value_vars=df1.columns[1:])
df = df.pivot(index='ID', columns = 'value', values = 'variable')
df = df.fillna(method = 'ffill', axis = 1)
df
df.pivot
两者都pd.pivot_table
失败的完整示例:
import pandas as pd
df1 = pd.DataFrame({ 'ID': {0: 10, 1: 11, 2: 12},
'Task1': {0: 1, 1: 1, 2: 1},
'Task2': {0: 4, 1: 3, 2: 3},
'Task3': {0: 4, 1: 4, 2: 4},
'Task4': {0: 6, 1: 5, 2: 6}})
df = pd.melt(df1, id_vars=['ID'], value_vars=df1.columns[1:])
# df = df.pivot(index='ID', columns = 'value', values = 'variable')
df = df.pivot_table(index='ID', columns = 'value', values = 'variable')
df = df.fillna(method = 'ffill', axis = 1)
df
解决方案
我很确定这不是最好的方法,但它是一种方法。
import pandas as pd
import numpy as np
df = pd.DataFrame({'ID': {0: 10, 1: 11, 2: 12},
'Task1': {0: 1, 1: 1, 2: 1},
'Task2': {0: 4, 1: 3, 2: 3},
'Task3': {0: 4, 1: 4, 2: 4},
'Task4': {0: 6, 1: 5, 2: 6}})
df1 = pd.melt(df, id_vars=['ID'], value_vars=df.columns[1:])
df1['value'] = df1['value'].astype(int)
df1.set_index(['ID','value'], inplace=True)
df_max_val = df.set_index('ID').max().max()
ids = df['ID'].tolist()*df_max_val
values = list(np.array([[i]*len(set(ids)) for i in range(1, df_max_val+1)]).flatten())
df2 = pd.DataFrame({'ID':ids,
'value':values})
df2.set_index(['ID','value'], inplace=True)
df3 = df2.merge(df1, left_index=True, right_index=True, how='outer')
df3 = df3.reset_index().drop_duplicates(subset=['ID','value'], keep='last')
df3 = pd.concat([df3[df3['ID']==i].fillna(method='ffill') for i in df3['ID'].unique()])
df3 = df3.pivot(index='ID', columns='value', values='variable')
推荐阅读
- javascript - 由于路径错误,Electron 找不到模块
- sap-cloud-sdk - 使用 SDK > 3.0 进行缓存 - 未配置 CachingProviders
- mysql - 如何创建数据库模式,使一名员工只能属于一个部门?
- python - 在 PyOpenGL 中切换 Y 轴和 Z 轴
- angular - 如果在 Angular 7 中引导选项卡集的 tabContent 内有其他条件
- javascript - scrollIntoView() 方法实现
- nlp - 如何从现有的文本集群中提取主题?
- sql - SQL查询解释确认
- karate - 空手道加特林 - 从报告中排除特定请求或功能
- amazon-web-services - AWS 负载均衡器和自动扩展