[英]pandas groupby and join lists
我有一个 dataframe df,有两列,我想按一列分组并加入属于同一组的列表,例如:
column_a, column_b
1, [1,2,3]
1, [2,5]
2, [5,6]
处理后:
column_a, column_b
1, [1,2,3,2,5]
2, [5,6]
我想保留所有重复项。 我有以下问题:
提前致谢。
object
dtype 是一个包罗万象的 dtype,基本上意味着不是 int、float、bool、datetime 或 timedelta。 所以它将它们存储为一个列表。 convert_objects
尝试将一列转换为这些数据类型之一。
你要
In [63]: df
Out[63]:
a b c
0 1 [1, 2, 3] foo
1 1 [2, 5] bar
2 2 [5, 6] baz
In [64]: df.groupby('a').agg({'b': 'sum', 'c': lambda x: ' '.join(x)})
Out[64]:
c b
a
1 foo bar [1, 2, 3, 2, 5]
2 baz [5, 6]
这将按a
列中的值对数据框进行分组。 阅读更多关于groupby 的信息。
这是做一个常规的列表sum
(串联)就像[1, 2, 3] + [2, 5]
与结果[1, 2, 3, 2, 5]
df.groupby('column_a').agg(sum)
这是有效的,因为运算符重载sum
将列表连接在一起。 结果 df 的索引将是column_a
的值:
使用 numpy 和简单的“for”或“map”:
import numpy as np
u_clm = np.unique(df.column_a.values)
all_lists = []
for clm in u_clm:
df_process = df.query('column_a == @clm')
list_ = np.concatenate(df.column_b.values)
all_lists.append((clm, list_.tolist()))
df_sum_lists = pd.DataFrame(all_lists)
对于大型数据集,它比简单的“groupby-agg-sum”方法快 350 倍。
上面提出的使用df.groupby('column_a').agg(sum)
的方法df.groupby('column_a').agg(sum)
有效。 但是,您必须确保您的列表仅包含integers
,否则输出将不同。
如果要将所有列表项转换为整数,可以使用:
df['column_a'] = df['column_a'].apply(lambda x: list(map(int, x)))
接受的答案建议使用groupby.sum
,它适用于少量列表,但是使用 sum 连接列表是quadratic 。
对于大量列表,更快的选择是使用itertools.chain
或列表推导:
df = pd.DataFrame({'column_a': ['1', '1', '2'],
'column_b': [['1', '2', '3'], ['2', '5'], ['5', '6']]})
itertools.chain
:
from itertools import chain
out = (df.groupby('column_a', as_index=False)['column_b']
.agg(lambda x: list(chain.from_iterable(x)))
)
列表理解:
out = (df.groupby('column_a', as_index=False, sort=False)['column_b']
.agg(lambda x: [e for l in x for e in l])
)
output:
column_a column_b
0 1 [1, 2, 3, 2, 5]
1 2 [5, 6]
使用示例的 n 次重复来显示要合并的列表数量的影响:
test_df = pd.concat([df]*n, ignore_index=True)
注意。 还比较了numpy方法( agg(lambda x: np.concatenate(x.to_numpy()).tolist())
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.