合并数据框时按列分组

时间:2019-04-29 12:35:09

标签: python pandas dataframe merge

我正在从DynamoDB中读取几张表,并在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'))

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

2 个答案:

答案 0 :(得分:1)

这是一种借助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

参考文献:

答案 1 :(得分:0)

以下是@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