如何合并多列中具有重复值的行

时间:2019-05-08 05:49:41

标签: python pandas

我想选择和合并与其他两列具有相同值的行(例如SQL中的主键)。我应该使用什么功能?

我尝试使用df.duplicate(subset = ...),但似乎没有给我正确的结果。

例如,我要合并'col B'和'col D'的值相同的行。

所以这个df会变成

     col a   'col B'    col c   'col D'    col e
''''''''''''''''''''''''''''''''''''''''''''''''''''''
 0     a       ABC-1     nan      ABCD      b,c
 1     a       ABC-2     nan      ABCD      aaa
 2     b       ABC-1      c       ABCD      b,c
 3     c       ABC-1     a,b      ABCD     b,c,d
 4     nan     ABC-3      c       AACE      b,c

这个

      col a   'col B'    col c   'col D'    col e
''''''''''''''''''''''''''''''''''''''''''''''''''''
 0     a,c     ABC-1    a,b,c     ABCD      b,c,d
 1      a      ABC-2     nan      ABCD      aaa
 2     nan     ABC-3      c       AACE      b,c

预先感谢

2 个答案:

答案 0 :(得分:1)

如果顺序对于没有NaN的拆分值并不重要,请在GroupBy.agg的自定义函数中转换为集合和join

def f(x):
    out = set([z for y in x.dropna() for z in y.split(',')])
    return ','.join(out) if bool(out) else np.nan

df = df.groupby(['col B','col D']).agg(f).reset_index().reindex(columns=df.columns)
print (df)
   col a  col B  col c col D  col e
0  c,a,b  ABC-1  a,c,b  ABCD  c,b,d
1      a  ABC-2    NaN  ABCD    aaa
2    NaN  ABC-3      c  AACE    c,b

如果订单很重要,请使用OrderedDict

from collections import OrderedDict

def f(x):
    out = OrderedDict.fromkeys([z for y in x.dropna() for z in y.split(',')]).keys()
    return ','.join(out) if bool(out) else np.nan

df = df.groupby(['col B','col D']).agg(f).reset_index().reindex(columns=df.columns)
print (df)
   col a  col B  col c col D  col e
0  a,b,c  ABC-1  c,a,b  ABCD  b,c,d
1      a  ABC-2    NaN  ABCD    aaa
2    NaN  ABC-3      c  AACE    b,c

答案 1 :(得分:0)

您还可以查看以下解决方案。

groups = df.groupby(['b','d'])

def reduce_values(dataframe):
    vals = []
#     print(dataframe.columns)
    for i in dataframe.columns:
        if dataframe[i].dropna().count():
            vals.append(','.join(set(dataframe[i].dropna().str.split(',').sum())))
        else:
            vals.append(dataframe[i][dataframe[i].index[-1]])
    return vals


# ndf

ndf = groups.apply(lambda x: pd.DataFrame([reduce_values(x)],columns=[i for i in x.columns if i not in groups.size().index.names])).reset_index(level=2,drop=True)

print(ndf)