当所有其他列值相同时,将列中多行的值折叠到数组中

问题描述 投票:0回答:3

我有一个有 7 列的表,其中每隔几行就有 6 列保持不变,只有第 7 列发生变化。我想将所有这些行合并为一行,并将第 7 列的值合并为一个列表。

所以如果我有这个数据框:

   A  B  C
0  a  1  2
1  b  3  4
2  c  5  6
3  c  7  6

我想把它转换成这样:

   A       B  C
0  a       1  2
1  b       3  4
2  c  [5, 7]  6

由于第 2 行和第 3 行中 A 列和 C 列的值相同,因此它们将折叠成一行,并且 B 列的值将合并到一个列表中。

熔化、爆炸、旋转似乎没有这样的功能。如何使用 Pandas 实现这一目标?

python-3.x pandas
3个回答
2
投票

GroupBy.agg
与自定义 lambda 函数一起使用,最后添加
DataFrame.reindex
以获得与原始列相同的顺序:

f = lambda x: x.tolist() if len(x) > 1 else x
df = df.groupby(['A','C'])['B'].agg(f).reset_index().reindex(df.columns, axis=1)

您还可以动态创建列名称,例如:

changes = ['B']
cols = df.columns.difference(changes).tolist()

f = lambda x: x.tolist() if len(x) > 1 else x
df = df.groupby(cols)[changes].agg(f).reset_index().reindex(df.columns, axis=1)
print (df)
   A       B  C
0  a       1  2
1  b       3  4
2  c  [5, 7]  6

对于列中的所有列表,解决方案更简单:

changes = ['B']
cols = df.columns.difference(changes).tolist()

df = df.groupby(cols)[changes].agg(list).reset_index().reindex(df.columns, axis=1)
print (df)
   A       B  C
0  a     [1]  2
1  b     [3]  4
2  c  [5, 7]  6

2
投票

这是另一种使用

pivot_table
applymap
的方法:

(df.pivot_table(index='A',aggfunc=list).applymap(lambda x: x[0] if len(set(x))==1 else x)
                                                                 .reset_index())

   A       B  C
0  a       1  2
1  b       3  4
2  c  [5, 7]  6

0
投票

对于 SparkSQL 或 PySpark,您可以使用

collect_list()
(docs)。但是,如果您想更进一步,
collect_set()
(docs) 将返回一个不同的数组。

我知道这不是 pandas,但在 2025 年我认为 Spark 是相关的。

© www.soinside.com 2019 - 2024. All rights reserved.