分组合并熊猫列的系列(本身就是一个系列)

Posted

技术标签:

【中文标题】分组合并熊猫列的系列(本身就是一个系列)【英文标题】:Merge Series of a pandas column (which is a Series itself) in groups 【发布时间】:2017-04-05 15:57:39 【问题描述】:

我有一个 pandas 数据框,其中一列是 Series 本身。例如:

df.head()

Col1    Col2  
1       ["name1","name2","name3"]  
1       ["name3","name2","name4"]  
2       ["name1","name2","name3"] 
2       ["name1","name5","name6"] 

我需要将 Col2 连接成 Col1 组。我想要类似的东西

Col1    Col2  
1       ["name1","name2","name3","name4"]  
2       ["name1","name2","name3","name5","name6"]

我尝试使用 groupby 作为

.agg("Col2":lambda x: pd.Series.append(x))

但这会引发错误,说需要两个参数。我还尝试在 agg 函数中使用 sum 。因错误而失败并不会减少。

我该怎么做?

【问题讨论】:

【参考方案1】:

您可以将groupbyapply 自定义函数一起使用,其中首先将嵌套列表按chain(最快solution)展平,然后通过set 删除重复项,转换为list 并最后排序:

import pandas as pd
from  itertools import chain

df = pd.DataFrame('Col1':[1,1,2,2],
                   'Col2':[["name1","name2","name3"],
                           ["name3","name2","name4"],
                           ["name1","name2","name3"],
                           ["name1","name5","name6"]])

print (df)
   Col1                   Col2
0     1  [name1, name2, name3]
1     1  [name3, name2, name4]
2     2  [name1, name2, name3]
3     2  [name1, name5, name6]
print (df.groupby('Col1')['Col2']
         .apply(lambda x: sorted(list(set(list(chain.from_iterable(x))))))
         .reset_index())
   Col1                                 Col2
0     1         [name1, name2, name3, name4]
1     2  [name1, name2, name3, name5, name6]

解决方案可以更简单,只需要chainsetsorted

print (df.groupby('Col1')['Col2']
         .apply(lambda x: sorted(set(chain.from_iterable(x))))
         .reset_index())

   Col1                                 Col2
0     1         [name1, name2, name3, name4]
1     2  [name1, name2, name3, name5, name6]

【讨论】:

【参考方案2】:

是的,你不能在这样的分类数据上使用.aggby。无论如何,这是我在 numpy 的帮助下解决问题的方法。 (为了清楚起见,注释)

import numpy as np

# Set group by ("Col1") unique values
groupby = df["Col1"].unique()

# Create empty dict to store values on each iteration
d = 

for i,val in enumerate(groupby):

    # Set "Col1" key, to the unique value (e.g., 1)
    d.setdefault("Col1",[]).append(val)

    # Create empty list to store values from "Col2"
    col2_unis=[]

    # Create sub-DataFrame for each unique groupby value
    sdf = df.loc[df["Col1"]==val]

    # Loop through the 2D-array/Series "Col2" and append each 
    # value to col_unis (using list comprehension)
    col2_unis.append([[j for j in array] for i,array in enumerate(sdf["Col2"].values)])

    # Set "Col2" key, to be unique values of col2_unis
    d.setdefault("Col2",[]).append(np.unique(col2_unis))

new_df = pd.DataFrame(d)

print(new_df)

更精简的版本如下所示:

d = 
for i,val in enumerate(df["Col1"].unique()):
    d.setdefault("Col1",[]).append(val)
    sdf = df.loc[df["Col1"]==val]
    d.setdefault("Col2",[]).append(np.unique([[j for j in array] for i,array in enumerate(df.loc[df["Col1"]==val, "Col2"].values)]))
new_df = pd.DataFrame(d)
print(new_df)

通过查看this related SO question,了解有关 Python 的 .setdefault() 字典函数的更多信息。

【讨论】:

以上是关于分组合并熊猫列的系列(本身就是一个系列)的主要内容,如果未能解决你的问题,请参考以下文章

合并具有不同索引的熊猫系列(对齐一个索引)

如何将日期和小时列合并到熊猫系列中的一个索引列中?

如何按索引级别和值对分组的多索引熊猫系列进行排序?

在熊猫中循环合并多个系列

格式化按两列分组的熊猫数据系列,并在第三个重新采样,平均值为 dict

如果日期时间索引的差异小于熊猫系列的 5 分钟,则分组