Pandas 按列表列中的元素对数据帧进行分组

Pandas 按列表列中的元素对数据帧进行分组,pandas,list,dataframe,group-by,aggregate,Pandas,List,Dataframe,Group By,Aggregate,我试图通过按列表列中的元素分组来获取数据帧中的列的聚合和。我将创建一个虚拟数据集来表示我正在使用的数据: preg_df=pd.DataFrame({'Diag_code':[[O1414','O4103X0','O365930','O76'], [O200',N3000',M545',R102',R110',Z3A01'], [O365922',O30032',O09512',Z3A26'], [O2341',O200',Z3A01'], [O209',Z3A01'], “前三个月”:[0,1

我试图通过按列表列中的元素分组来获取数据帧中的列的聚合和。我将创建一个虚拟数据集来表示我正在使用的数据:

preg_df=pd.DataFrame({'Diag_code':[[O1414','O4103X0','O365930','O76'],
[O200',N3000',M545',R102',R110',Z3A01'],
[O365922',O30032',O09512',Z3A26'],
[O2341',O200',Z3A01'],
[O209',Z3A01'],
“前三个月”:[0,1,0,1,1],
“中期妊娠”:[0,0,1,0,0],
‘妊娠晚期’:[1,0,0,0,0]})
我想从该数据创建一个新的数据框,该数据框按preg_df的“Diag_codes”列中包含的诊断代码分组。我已经能够通过以下for循环实现这一点:

# Create a list of unique diagnosis codes from the preg_df dataframe
diagnoses = list(set([item for sublist in preg_df.Diag_Codes.tolist() for item in sublist]))

diag_dfs = []

for i in diagnoses:
    
    diag_indices = []
    diag_df = pd.DataFrame()
    
    # Get the indices at which the diagnosis code exists within the 'Diag_Codes' column
    [diag_indices.append(index) for index, row in preg_df.iterrows() if i in preg_df.loc[index, 'Diag_Codes']]
    
    # Subset the dataframe to obtain only records in which the diagnosis code exists within 'Diag_Codes' column
    diag_df = preg_df.loc[diag_indices, 'First_Trimester':]
    diag_df['Diag_Code'] = i
    diag_df['Total_Cases'] = len(diag_indices)
    
    # Group by diagnosis code and the total number of cases and get the aggregate sum of all other columns
    diag_df = diag_df.groupby(['Diag_Code', 'Total_Cases']).sum()
    diag_dfs.append(diag_df)
    
diag_data = pd.concat(diag_dfs).sort_values(by=['Total_Cases'], ascending=False)
diag_data.head()

上面的for循环确实生成了我感兴趣的从原始数据集创建的数据帧,但是,该方法不适用于大型数据集。我正在使用的实际数据帧大约有500万行,包含数万个唯一的诊断代码。因此,对于我来说,通过使用上面共享的for循环来获得所需的数据帧是不可行的,在该数据帧中,我通过诊断代码进行分组。有没有一种更有效的方法可以让我在使用更大的数据集时完成所需的输出?

这应该可以。它会将每个列表诊断代码与它们自己的列和行堆叠在一起,因此使用它们会更容易

In:

diag_codes = pd.DataFrame(preg_df["Diag_Codes"].tolist()).stack()
diag_codes.index = diag_codes.index.droplevel(-1)
diag_codes.name = "diag_codes"
grouped_codes = preg_df.join(diag_codes).groupby('diag_codes').sum()
grouped_codes
输出:

Out:

    First_Trimester     Second_Trimester    Third_Trimester
diag_codes          
M545    1   0   0
N3000   1   0   0
O09512  0   1   0
O1414   0   0   1
O200    2   0   0
O209    1   0   0
O2341   1   0   0
O30032  0   1   0
O365922     0   1   0
O365930     0   0   1
O4103X0     0   0   1
O76     0   0   1
R102    1   0   0
R110    1   0   0
Z3A01   3   0   0
Z3A26   0   1   0
            First_Trimester  Second_Trimester  Third_Trimester
Diag_Codes                                                    
M545                      1                 0                0
N3000                     1                 0                0
O09512                    0                 1                0
O1414                     0                 0                1
O200                      2                 0                0
O209                      1                 0                0
O2341                     1                 0                0
O30032                    0                 1                0
O365922                   0                 1                0
O365930                   0                 0                1
O4103X0                   0                 0                1
O76                       0                 0                1
R102                      1                 0                0
R110                      1                 0                0
Z3A01                     3                 0                0
Z3A26                     0                 1                0
如果需要,请告诉我进行任何修复,否则您可以继续执行此操作。告诉我te数据库的尺寸,这样我就可以知道这是否得到了很好的优化。请记住,始终尝试使用内置函数并使用“for”循环作为您的最后手段。

让我们试试:

preg_df.explode('Diag_Codes').groupby('Diag_Codes').sum()
输出:

Out:

    First_Trimester     Second_Trimester    Third_Trimester
diag_codes          
M545    1   0   0
N3000   1   0   0
O09512  0   1   0
O1414   0   0   1
O200    2   0   0
O209    1   0   0
O2341   1   0   0
O30032  0   1   0
O365922     0   1   0
O365930     0   0   1
O4103X0     0   0   1
O76     0   0   1
R102    1   0   0
R110    1   0   0
Z3A01   3   0   0
Z3A26   0   1   0
            First_Trimester  Second_Trimester  Third_Trimester
Diag_Codes                                                    
M545                      1                 0                0
N3000                     1                 0                0
O09512                    0                 1                0
O1414                     0                 0                1
O200                      2                 0                0
O209                      1                 0                0
O2341                     1                 0                0
O30032                    0                 1                0
O365922                   0                 1                0
O365930                   0                 0                1
O4103X0                   0                 0                1
O76                       0                 0                1
R102                      1                 0                0
R110                      1                 0                0
Z3A01                     3                 0                0
Z3A26                     0                 1                0