Python 分组数据帧并将多个值收集到集合中

Python 分组数据帧并将多个值收集到集合中,python,pandas,dataframe,data-munging,Python,Pandas,Dataframe,Data Munging,假设我有以下数据帧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

假设我有以下数据帧
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
    分组,即
    A
    列是索引,每行
    A
    的值是唯一的

  • B
    C
    包含出现的值的集合。对于
    A=“foo”
    B
    要么是
    “一”
    ,要么是
    “两”
    ,而对于
    “条”
    ,它只是
    “两”

    • 从逻辑上讲,这应该是一个集合,其中出现的每个值都只出现一次。它可能是一个Python
      ,但我也在问,用熊猫来表示它最优雅的方式是什么
  • D
    不包含集合,因为对于
    foo
    D
    总是0,对于
    bar
    总是1。如果索引值和列值之间始终存在1:1的关系,则该列不应包含集合


我原以为会有一行聚合a la
df1.groupby(“a”).aggregate\u like_this()
,但到目前为止我没有找到它。

使用
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
的哪些值与
D
具有1:1的关系,请使用
groupby
+
nunique
进行检查,然后相应地过滤数据集

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

这里我需要事先知道D列与索引值之间的关系是1:1。这意味着我需要手动测试每一列。有没有办法让pandas自动执行此操作?您编写
{'D':'first'}
,告诉pandas为
D
列取第一个值,因为我告诉过您,
D
列有一个属性,即
a
的每个值只有一个
D
。但是如果我们不知道呢?@clstaudt它会盲目地取第一个值,不管我们是否知道D和A之间的关系。如果没有唯一值,您想怎么做?@Wen这是一个选项,但我认为
np.unique
比大型数组上的
set
更快。。。此外,
D
不能成为列表列。根据他的样本数据,该集合在一个组中包含[0,1]。-)