合并数据框时按列分组

Posted

技术标签:

【中文标题】合并数据框时按列分组【英文标题】:Group by columns while merging data frames 【发布时间】:2019-09-18 02:06:41 【问题描述】:

我在 for 循环中将多个数据帧合并为一个数据帧。像这样:

import pandas as pd
import numpy as np

df1 = pd.DataFrame(data=np.random.randint(0,100,(2,5)),columns=list('ABCDE'))
df2 = pd.DataFrame(data=np.random.randint(0,100,(2,5)),columns=list('GHABC'))
df1 = df1.merge(df2, how='outer', left_index=True, right_index=True,suffixes=('', '_' + 'second'))

每个数据框中的几列具有相似的名称,因此每次有这样的列时,我都会添加一个后缀。它变得一团糟。此外,我希望能够快速访问第一个表、第二个表等中的所有列。有没有办法合并这些列但将它们保持为一个组?这样我就不需要更改列名并且可以更轻松地访问每个数据集的所有列?

【问题讨论】:

您可以为每个数据框添加一列data_source 并垂直连接它们。 这是一个好主意,可以快速访问它们的来源,但是如果有重复的名称,我仍然需要更改列名。是吗? 如果你垂直加入它们就不会,而不是像现在这样水平加入。 【参考方案1】:

这是@QuangHoang 在他们的comment 中提出的说明:

import pandas as pd


df1 = pd.DataFrame(data=np.random.randint(0, 100, (2, 5)),
                   columns=list('ABCDE'))
df2 = pd.DataFrame(data=np.random.randint(0, 100, (2, 5)),
                   columns=list('GHABC'))
dfs = [df1, df2]
for source_index, df in enumerate(dfs):
    df['data_source'] = source_index
result = pd.concat(dfs)
print(result)

将使您的所有数据框垂直连接:

    A   B   C     D     E     G     H  data_source
0  66  52  16  73.0  59.0   NaN   NaN            0
1  73  64  59  31.0  13.0   NaN   NaN            0
0  72  79  45   NaN   NaN  30.0   0.0            1
1  45  52  40   NaN   NaN   2.0  80.0            1

要循环访问每个组,您可以这样做:

for source_index, df in result.groupby('data_source'):
    print(df.dropna(axis=1))
    A   B   C     D     E  data_source
0  66  52  16  73.0  59.0            0
1  73  64  59  31.0  13.0            0
    A   B   C     G     H  data_source
0  72  79  45  30.0   0.0            1
1  45  52  40   2.0  80.0            1

或来源by an index:

gb = result.groupby('data_source')
source_index = 0
first_group = gb.get_group(source_index).dropna(axis=1)
print(first_group)
    A   B   C     D     E  data_source
0  66  52  16  73.0  59.0            0
1  73  64  59  31.0  13.0            0

【讨论】:

感谢您的详细解释。我的数据集很大,它们共有的列数并不多(与总列数相比)。我不确定是否应该创建一个包含大量 NaN 的大型数据框。 此外,我正在阅读的列将全部用于训练模型,因此保持它们水平连接仍然有意义【参考方案2】:

这是一种在MultiIndex 的帮助下水平合并数据帧的方法,与垂直合并相比,它具有一些优势。例如,您不会有很多 NaN 字段,并且 dtype 不会像水平合并的情况那样从 int 更改为 float

import numpy as np
import pandas as pd


df1 = pd.DataFrame(data=np.random.randint(0, 100, (2, 5)),
                   columns=list('ABCDE'))
df2 = pd.DataFrame(data=np.random.randint(0, 100, (2, 5)),
                   columns=list('GHABC'))
dfs = [df1, df2]
result = pd.concat(dfs, axis=1, keys=range(len(dfs)))
print(result)

这将给出:

    0                   1                
    A   B   C   D   E   G   H   A   B   C
0  41  49  13  36  57  28  12  82  18  67
1  72  91  34  17  12   6  67  98  36  25

您可以循环访问每个组:

for source_index, df in result.groupby(axis=1, level=0):
    print(df)
    0                
    A   B   C   D   E
0  41  49  13  36  57
1  72  91  34  17  12
    1                
    G   H   A   B   C
0  28  12  82  18  67
1   6  67  98  36  25

或单独:

gb = result.groupby(axis=1, level=0)
first_group = gb.get_group(0)
print(first_group)
    0                
    A   B   C   D   E
0  41  49  13  36  57
1  72  91  34  17  12

参考文献:

Concatenate pandas columns under new multi-index level How to do group by on a multiindex in pandas? How to access pandas groupby dataframe by key

【讨论】:

感谢 Georgy,这正是我要寻找的!

以上是关于合并数据框时按列分组的主要内容,如果未能解决你的问题,请参考以下文章

熊猫数据框按列位置分组

按列对分组数据帧进行采样

如何在 Pandas 数据框中按列值分组

熊猫数据框分组和求和,组内,跨行值而不是按列

按列值的前导字符对数据行进行分组

在 Python 中按列分组以获得总计数