Skip to main content
 首页 » 编程设计

python之使用分组依据转换数据框并包含额外的列值

2025年05月04日14shanyou

给定这个数据框:

import numpy as np 
import pandas as pd 
 
df = pd.DataFrame([['a1' , '1'], ['a2' , '2'], ['stop' , '3'], ['a2' , '4'], ['a4' , '5'], ['a5' , '6'], ['stop' , '7'], ['a6' , '8']], 
                      columns=['a' , 'b']) 
mask = df['a'].eq('stop') 
print(df) 
      a  b 
0  a1    1 
1  a2    2 
2  stop  3 
3  a2    4 
4  a4    5 
5  a5    6 
6  stop  7 
7  a6    8 

处理将数据帧转换为:

stop = mask[::-1].idxmax() 
mask = mask[:stop] 
c = df['a'][:stop].copy() 
c.groupby(mask.cumsum()).apply(lambda s: s[s!='stop'].tolist()) 
a 
0    [a1, a2]     
1    [a2, a4, a5] 
Name: a, dtype: object 

当遇到“停止”时,会创建一个包含先前值的新数组。

我正在尝试创建一个元组列表,其中 b 列从数据帧 df 映射到 a 列的 id。这是创建时预期的数据框结构:

0    [(a1 , 1), (a2 , 2)]     
1    [(a2 , 3), (a4 , 4), (a5 , 5)] 

这是我到目前为止的尝试:

def get_value(x) :  
    to_ret = [] 
    for a in x :  
        to_ret.append( (a , df[df['a'] == a]['b'])) 
    return to_ret 
 
 
c1 = c.groupby(mask.cumsum()).apply(lambda s: s[s!='stop'].tolist()) 
c1.map(lambda x : get_value(x)) 

呈现:

a 
0    [(a1, [1]), (a2, [2, 4])]            
1    [(a2, [2, 4]), (a4, [5]), (a5, [6])] 
Name: a, dtype: object 

这似乎是一个简单问题的复杂部分解决方案。是否有转换此数据框的替代方法?

请您参考如下方法:

您似乎可以将数据框转换为 2 元组系列并将 that 与类似的东西分组(groupby + apply + tolist) -

df.apply(tuple, 1)[:stop]\ 
  .groupby(mask.cumsum())\ 
  .apply(lambda s: s[s.str[0] !='stop'].tolist()) 
 
a 
0             [(a1, 1), (a2, 2)] 
1    [(a2, 4), (a4, 5), (a5, 6)]