Pandas数据框通过逗号将重复列组合成一个单独的数据

时间:2016-06-20 21:52:54

标签: python pandas dataframe

我的数据框没有重复的列名。如果找到重复的列名称,请将重复列合并为一列。我还想保留用逗号分隔的重复列数据。任何人都可以建议一种方法来做到这一点。

我在下面构建了一个例子。在我的实际数据框中,列名称是未知的。

输入数据框:

  Col1 Col2 Col3 Col2
A  CA1  CA5  CA3  CA5
B  CB1  CB5  CB3  CB5
C  CC1  CC5  CC3  CC5
D  CD1  CD5  CD3  None
E  CE1  CE5  CE3  CE5

可以阅读:

df = pd.read_clipboard(names=['Col1','Col2','Col3','Col2'], skiprows=1)

输出DataFrame:

  Col1     Col2 Col3
A  CA1  CA5,CA5  CA3
B  CB1  CB5,CB5  CB3
C  CC1  CC5,CC5  CC3
D  CD1  CD5  CD3
E  CE1  CE5,CE5  CE3

4 个答案:

答案 0 :(得分:5)

你可以这样做:

df.T.groupby(level=0).agg(','.join).T

数据:

In [207]: df
Out[207]:
      Col1 Col2 Col1 Col2 Col3
Index
A      CA1  CA2  CA3  CA5  ZA1
B      CB1  CB2  CB3  CB5  ZA2
C      CC1  CC2  CC3  CC5  ZA3
D      CD1  CD2  CD3  CD5  ZA4
E      CE1  CE2  CE3  CE5  ZA5

输出:

In [208]: df.T.groupby(level=0).agg(','.join).T
Out[208]:
          Col1     Col2 Col3
Index
A      CA1,CA3  CA2,CA5  ZA1
B      CB1,CB3  CB2,CB5  ZA2
C      CC1,CC3  CC2,CC5  ZA3
D      CD1,CD3  CD2,CD5  ZA4
E      CE1,CE3  CE2,CE5  ZA5

说明:

In [209]: df.T
Out[209]:
Index    A    B    C    D    E
Col1   CA1  CB1  CC1  CD1  CE1
Col2   CA2  CB2  CC2  CD2  CE2
Col1   CA3  CB3  CC3  CD3  CE3
Col2   CA5  CB5  CC5  CD5  CE5
Col3   ZA1  ZA2  ZA3  ZA4  ZA5

In [210]: df.T.groupby(level=0).agg(','.join)
Out[210]:
Index        A        B        C        D        E
Col1   CA1,CA3  CB1,CB3  CC1,CC3  CD1,CD3  CE1,CE3
Col2   CA2,CA5  CB2,CB5  CC2,CC5  CD2,CD5  CE2,CE5
Col3       ZA1      ZA2      ZA3      ZA4      ZA5

答案 1 :(得分:4)

你也可以:

df.groupby(df.columns, axis=1).agg(lambda x: ','.join(x.values)))

      Col1     Col2 Col3
Index                   
A      CA1  CA2,CA5  CA3
B      CB1  CB2,CB5  CB3
C      CC1  CC2,CC5  CC3
D      CD1  CD2,CD5  CD3
E      CE1  CE2,CE5  CE3

详细信息:使用.groupby()上的df.columns对重复项进行分组:

df.groupby(df.columns, axis=1).apply(lambda x: x.info())

<class 'pandas.core.frame.DataFrame'>
Index: 5 entries, A to E
Data columns (total 1 columns):
Col1    5 non-null object
dtypes: object(1)
memory usage: 80.0+ bytes
<class 'pandas.core.frame.DataFrame'>
Index: 5 entries, A to E
Data columns (total 2 columns):
Col2    5 non-null object
Col2    5 non-null object
dtypes: object(2)
memory usage: 120.0+ bytes
<class 'pandas.core.frame.DataFrame'>
Index: 5 entries, A to E
Data columns (total 1 columns):
Col3    5 non-null object
dtypes: object(1)

然后,使用.agg()','.join()一起折叠.values列中的grouped,其内容如下:

df.groupby(df.columns, axis=1).apply(lambda x: x.values)

Col1                  [[CA1], [CB1], [CC1], [CD1], [CE1]]
Col2    [[CA5, CA5], [CB5, CB5], [CC5, CC5], [CD5, CD5...
Col3                  [[CA3], [CB3], [CC3], [CD3], [CE3]]

由于只有重复的列具有多个值,因此只会将它们连接起来,以便您获得:

      Col1     Col2 Col3
Index                   
A      CA1  CA5,CA5  CA3
B      CB1  CB5,CB5  CB3
C      CC1  CC5,CC5  CC3
D      CD1  CD5,CD5  CD3
E      CE1  CE5,CE5  CE3

使用None类型值,您可以:

df.groupby(df.columns, axis=1).apply(lambda x: x.apply(lambda y: ','.join([l for l in y if l is not None]), axis=1))

得到:

      Col1     Col2 Col3
Index                   
A      CA1  CA5,CA5  CA3
B      CB1  CB5,CB5  CB3
C      CC1  CC5,CC5  CC3
D      CD1      CD5  CD3
E      CE1  CE5,CE5  CE3

答案 2 :(得分:1)

发布此帖我感到很惭愧。但它确实有效。

df = pd.DataFrame(np.random.choice(('a', 'b', 'c'), (5, 4)), list('ABCDE'), ['Col1', 'Col2', 'Col3', 'Col2'])

pd.concat([pd.DataFrame(c) for i, c in df.iteritems()], axis=1, keys=range(len(df.columns))).swaplevel(0, 1, 1).sort_index(1).groupby(level=0, axis=1).apply(lambda df: df.apply(lambda x: ','.join(x.values), axis=1))

分解了一下。

df2 = pd.concat([pd.DataFrame(c) for i, c in df.iteritems()],
                axis=1, keys=range(len(df.columns)))

a1 = lambda df: df.apply(lambda x: ','.join(x.values), axis=1)
gb = df2.swaplevel(0, 1, 1).sort_index(1).groupby(level=0, axis=1)
gb.apply(a1)

  Col1 Col2 Col3
A    a  c,b    a
B    a  c,c    c
C    a  a,b    b
D    b  c,c    a
E    a  c,b    a

答案 3 :(得分:0)

这是一个函数,可以根据任务使用一些不同的方法快速合并列。如果不是 100% 的列被复制,则比 groupby 快...

import pandas as pd
import numpy as np

def merge_duplicated_columns(df, method="join", sep=","):
    duplicated =  df.columns[df.columns.duplicated()].unique()
    
    if method == "join":
        for d in duplicated:
            df[d] = df.pop(d).fillna("").astype(str).apply(
                sep.join, axis=1).str.replace(
                    r"(?<=\|)\|", "", regex=True).str.strip(sep).replace("", np.nan)   
            
    elif method == "unique":
        for d in duplicated:
            df[d] = df.pop(d).fillna("").astype(str).apply(
                lamba x: sep.join(x.unique()),                
                axis=1).str.replace(
                    r"(?<=\|)\|", "", regex=True).str.strip(sep).replace("", np.nan)             
                    
    elif method == "sum":
        for d in duplicated:
            df[d] = df.pop(d).sum(axis=1)
        
    return df