合并 DataFrame 中的重复列

Posted

技术标签:

【中文标题】合并 DataFrame 中的重复列【英文标题】:Combine duplicated columns within a DataFrame 【发布时间】:2012-10-16 05:40:38 【问题描述】:

如果我有一个包含相同名称的列的数据框,有没有办法将具有相同名称的列与某种函数(即 sum)结合起来?

例如:

In [186]:

df["NY-WEB01"].head()
Out[186]:
                NY-WEB01    NY-WEB01
DateTime        
2012-10-18 16:00:00  5.6     2.8
2012-10-18 17:00:00  18.6    12.0
2012-10-18 18:00:00  18.4    12.0
2012-10-18 19:00:00  18.2    12.0
2012-10-18 20:00:00  19.2    12.0

如何通过对列名相同的每一行求和来折叠 NY-WEB01 列(有一堆重复的列,而不仅仅是 NY-WEB01)?

【问题讨论】:

是的,这是Split-Apply-Combine,您的聚合函数是sum()。这是一个非常普遍的范式。顺便说一句,您是在“聚合”行,而不是“合并”它们。 另外,这里实际上是在组合行,而不是列。 (您正在根据具有相同值(不是“名称”)的某些列组合行)。您可能想更正您的标题。 【参考方案1】:

我相信这可以满足您的需求:

df.groupby(lambda x:x, axis=1).sum()

或者,根据 df 的长度,速度提高 3% 到 15%:

df.groupby(df.columns, axis=1).sum()

编辑:要将其扩展到总和之外,请使用 .agg().aggregate() 的缩写):

df.groupby(df.columns, axis=1).agg(numpy.max)

【讨论】:

是否可以仅针对特定列(具有重复的列名)?原因是如果某列被标识为Timestamp,pandas 会报错TypeError: Addition/subtraction of integers and integer-arrays with Timestamp is no longer supported.【参考方案2】:

熊猫 >= 0.20: df.groupby(level=0, axis=1)

这里不需要 lambda,也不需要显式查询 df.columnsgroupby 接受 level 参数,您可以与 axis 参数一起指定。这更干净,IMO。

# Setup
np.random.seed(0)
df = pd.DataFrame(np.random.choice(50, (5, 5)), columns=list('AABBB'))
df

    A   A   B   B   B
0  44  47   0   3   3
1  39   9  19  21  36
2  23   6  24  24  12
3   1  38  39  23  46
4  24  17  37  25  13

df.groupby(level=0, axis=1).sum()

    A    B
0  91    6
1  48   76
2  29   60
3  39  108
4  41   75

处理MultiIndex

另一个需要考虑的情况是在处理MultiIndex 列时。考虑

df.columns = pd.MultiIndex.from_arrays([['one']*3 + ['two']*2, df.columns])
df
  one         two    
    A   A   B   B   B
0  44  47   0   3   3
1  39   9  19  21  36
2  23   6  24  24  12
3   1  38  39  23  46
4  24  17  37  25  13

要跨上层执行聚合,请使用

df.groupby(level=1, axis=1).sum()

    A    B
0  91    6
1  48   76
2  29   60
3  39  108
4  41   75

或者,如果仅按上层聚合,则使用

df.groupby(level=[0, 1], axis=1).sum()

  one     two
    A   B   B
0  91   0   6
1  48  19  57
2  29  24  36
3  39  39  69
4  41  37  38

替代解释:删除重复的列

如果您来这里是想了解如何简单地删除重复列(不执行任何聚合),请使用Index.duplicated

df.loc[:,~df.columns.duplicated()]

    A   B
0  44   0
1  39  19
2  23  24
3   1  39
4  24  37

或者,要保留最后一个,请指定keep='last'(默认为'first'),

df.loc[:,~df.columns.duplicated(keep='last')]

    A   B
0  47   3
1   9  36
2   6  12
3  38  46
4  17  13

上述两种解决方案的groupby 替代方案分别是 df.groupby(level=0, axis=1).first()... .last()

【讨论】:

【参考方案3】:

对于常见的聚合函数,如summeanmedianmaxminstd,这是可能的更简单的解决方案 - 仅使用参数 axis=1 处理列和 @987654329 @:

#coldspeed samples
np.random.seed(0)
df = pd.DataFrame(np.random.choice(50, (5, 5)), columns=list('AABBB'))
print (df)

print (df.sum(axis=1, level=0))
    A    B
0  91    6
1  48   76
2  29   60
3  39  108
4  41   75

df.columns = pd.MultiIndex.from_arrays([['one']*3 + ['two']*2, df.columns])

print (df.sum(axis=1, level=1))
    A    B
0  91    6
1  48   76
2  29   60
3  39  108
4  41   75

print (df.sum(axis=1, level=[0,1]))
  one     two
    A   B   B
0  91   0   6
1  48  19  57
2  29  24  36
3  39  39  69
4  41  37  38

类似它适用于索引,然后使用axis=0 而不是axis=1

np.random.seed(0)
df = pd.DataFrame(np.random.choice(50, (5, 5)), columns=list('ABCDE'), index=list('aabbc'))
print (df)
    A   B   C   D   E
a  44  47   0   3   3
a  39   9  19  21  36
b  23   6  24  24  12
b   1  38  39  23  46
c  24  17  37  25  13

print (df.min(axis=0, level=0))
    A   B   C   D   E
a  39   9   0   3   3
b   1   6  24  23  12
c  24  17  37  25  13

df.index = pd.MultiIndex.from_arrays([['bar']*3 + ['foo']*2, df.index])

print (df.mean(axis=0, level=1))
      A     B     C     D     E
a  41.5  28.0   9.5  12.0  19.5
b  12.0  22.0  31.5  23.5  29.0
c  24.0  17.0  37.0  25.0  13.0

print (df.max(axis=0, level=[0,1]))
        A   B   C   D   E
bar a  44  47  19  21  36
    b  23   6  24  24  12
foo b   1  38  39  23  46
    c  24  17  37  25  13

如果需要使用firstlastsizecount等其他函数,则必须使用coldspeed answer

【讨论】:

以上是关于合并 DataFrame 中的重复列的主要内容,如果未能解决你的问题,请参考以下文章

基于Pandas.Dataframe中的多个列合并多个重复行

DataFrame合并以排除额外的索引列[重复]

合并具有来自两个不同列的匹配值的 DataFrame - Pandas [重复]

python-dataframe的合并(append, merge, concat, join)

如何在不重复列的情况下合并 Pandas 数据框

如何用pandas将某列one-hot编码后,修改原dataframe