1

假设我有以下数据框df1

     A    B  C   D 
0  foo  one  1  0
1  bar  two  2  1
2  foo  two  3  0
3  bar  two  4  1
4  foo  two  5  0
5  bar  two  6  1
6  foo  one  7  0
7  foo  two  8  1

我想把它变成这样的数据框df2

A     B            C                 D             
foo  [one,two]  [1,3,5,7,8]          0
bar  [two]          [2,4,6]          1

更确切地说:

  • 按 分组A,即 columnA是索引并且在每一行中 的值A是唯一的

  • BC包含发生的值的聚合集。For A = "foo", Bwas 非此即彼"one""two"而 for "bar"it is only "two"

    • 从逻辑上讲,这应该是一个集合,每个出现的值都恰好出现一次。它可能是 Python set,但我也在问最优雅的方式是用 pandas 来表示它
  • D不包含集合,因为 forfoo D始终为 0,forbar始终为 1。如果索引值和列值之间始终存在 1:1 的关系,则该列不应包含集合。

我预计会有一个单线聚合 a la df1.groupby("A").aggregate_like_this(),但到目前为止我还没有找到它。

4

1 回答 1

2

使用groupby+ agg

f = {'B' : lambda x: np.unique(x).tolist(), 
     'C' : lambda x: np.unique(x).tolist(), 
     'D' : 'first'
}

df.groupby('A', as_index=False).agg(f).reindex(columns=df.columns)

     A           B                C  D
0  bar       [two]        [2, 4, 6]  1
1  foo  [one, two]  [1, 3, 5, 7, 8]  0 

如果您无法提前确定哪些值与A具有 1:1 的关系,请使用+进行D检查,然后相应地过滤您的数据集。groupbynunique

x = df.groupby('A').D.nunique().eq(1)
df = df[df.A.isin(x[x].index)]
df

     A    B  C  D
1  bar  two  2  1
3  bar  two  4  1
5  bar  two  6  1

df.groupby('A', as_index=False).agg(f).reindex(columns=df.columns)

     A      B          C  D
0  bar  [two]  [2, 4, 6]  1
于 2017-11-01T12:12:07.507 回答