分组 pandas 数据框并将多个值收集到集合中
Grouping pandas dataframe and collecting multiple values into sets
假设我有以下数据框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
是 "one"
或 "two"
,而对于 "bar"
,它只是 "two"
。
- 从逻辑上讲,这应该是一个集合,其中出现的每个值都恰好出现一次。它可能是 Python
set
,但我也在问用 pandas 表示它的最优雅的方法是什么
列 D
不包含集合,因为对于 foo
D
总是 0 而对于 bar
它总是 1。如果有索引值和列值之间始终是 1:1 关系,则该列不应包含集合。
我希望像 la df1.groupby("A").aggregate_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
假设我有以下数据框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
是"one"
或"two"
,而对于"bar"
,它只是"two"
。- 从逻辑上讲,这应该是一个集合,其中出现的每个值都恰好出现一次。它可能是 Python
set
,但我也在问用 pandas 表示它的最优雅的方法是什么
- 从逻辑上讲,这应该是一个集合,其中出现的每个值都恰好出现一次。它可能是 Python
列
D
不包含集合,因为对于foo
D
总是 0 而对于bar
它总是 1。如果有索引值和列值之间始终是 1:1 关系,则该列不应包含集合。
我希望像 la df1.groupby("A").aggregate_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