熊猫拆分列并合并结果,索引重复

时间:2019-01-20 21:03:17

标签: python pandas

我有以下数据框:

ID     Type      Value
1        A         311
1        A         223
1        B        1233
2        A         424
2        A         553
3        A          11
3        B           4
3        B           5

我正在尝试通过拆分“类型”列来合并“ ID”列,以使每个ID都有自己的行以及类型A和类型B各自的列。在列“ A”和“ B”中,我想要在行中分配每个值的第一次出现。如果缺少A或B(或两者都缺少),我想分配NaN。为了使这个想法更清楚,下面的示例描述了我正在寻找的结果:

   ID       A           B
    1      311        1233
    2      424         NaN
    3       11           4

结果将保留为A出现的第一个值(而忽略A 223的第二个值)。由于ID 1中没有B的第二个值,因此它仅保留值1233。对于其他ID,此逻辑继续。

我一直在尝试使用.pivot使用

来解决这个问题
df.pivot(columns="Type",values="Value")

这有助于我分隔“类型”列,以便得到:

Type      A        B
  0      311      NaN
  1      223      NaN
  2      NaN     1233
  3      11         4

但是我无法将ID列作为索引传递,因为它给了我错误:

ValueError: Index contains duplicate entries, cannot reshape

在ID列上使用drop_duplicates会导致数据丢失。在熊猫中有什么方便的方法吗?

2 个答案:

答案 0 :(得分:3)

您需要先删除重复项,然后再进行数据透视。

df.drop_duplicates(['ID', 'Type']).pivot('ID', 'Type', 'Value')

Type      A       B
ID                 
1     311.0  1233.0
2     424.0     NaN
3      11.0     4.0

或者,将pivot_tableaggfunc='first'一起使用:

df.pivot_table(index='ID', columns='Type', values='Value', aggfunc='first')

Type      A       B
ID                 
1     311.0  1233.0
2     424.0     NaN
3      11.0     4.0

性能
这实际上取决于您的数据和组数。最好是根据自己的数据进行测试。

df_ = df.copy()
df = pd.concat([df_] * 10000, ignore_index=True)

%timeit df.pivot_table(index='ID', columns='Type', values='Value', aggfunc='first')
%timeit df.drop_duplicates(['ID', 'Type']).pivot('ID', 'Type', 'Value')
%timeit df.groupby(['ID', 'Type']).Value.first().unstack(1)

15.2 ms ± 272 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
8.63 ms ± 98 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
8.34 ms ± 246 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

答案 1 :(得分:2)

使用groupby first

df.groupby(['ID','Type']).Value.first().unstack()
Type      A       B
ID                 
1     311.0  1233.0
2     424.0     NaN
3      11.0     4.0

或将groupby headpivot一起使用

df.groupby(['ID','Type'],as_index=False).head(1).pivot('ID', 'Type', 'Value')
Type      A       B
ID                 
1     311.0  1233.0
2     424.0     NaN
3      11.0     4.0
相关问题