【问题标题】:Method to set new Multiindex columns from different dataframe从不同数据框中设置新的多索引列的方法
【发布时间】:2016-09-25 21:59:14
【问题描述】:

给定一个带有 MultiIndex 列的 DataFrame (d),我想将另一个 DataFrame (d2) 设置为“多列”之一,这样顶层有一些标签,而二级标签匹配原来的那些:

nr.seed(0)
abc = ['a', 'b', 'c']
mi = pd.MultiIndex.from_product([['A'], abc])
d = DataFrame(np.random.randint(0, 10, (4, 3)), columns=mi)
d
   A      
   a  b  c
0  5  0  3
1  3  7  9
2  3  5  2
3  4  7  6

d2 = DataFrame(np.random.randint(0, 10, (4, 3)), columns=abc)
d2
   a  b  c
0  8  8  1
1  6  7  7
2  8  1  5
3  9  8  9

如果可能,我想使用一个完成以下 forloop 的内置方法加入它们:

for c2 in d2:
    d['B', c2] = d2[c2]
d
   A        B      
   a  b  c  a  b  c
0  5  0  3  8  8  1
1  3  7  9  6  7  7
2  3  5  2  8  1  5
3  4  7  6  9  8  9

对于具有单级列的 DataFrame:

d3 = d.copy()
d3.columns = d3.columns.droplevel(0)
d3 = d3.rename(columns=dict(zip('abc', 'def')))
d3
   d  e  f
0  5  0  3
1  3  7  9
2  3  5  2
3  4  7  6

我可以做到以下几点:

d3[d2.columns] = d2
d3
   d  e  f  a  b  c
0  5  0  3  8  8  1
1  3  7  9  6  7  7
2  3  5  2  8  1  5
3  4  7  6  9  8  9

但是当我用 MultiIndexed DataFrame 尝试这个时,我得到了错误:

d['B', tuple(d2.columns)] = d2
=> ValueError: Wrong number of items passed 3, placement implies 1
d['B'][tuple(d2.columns)] = d2
=> KeyError: 'B'

有没有内置方法可以做到这一点? (基本上一次对多个列执行this)。

【问题讨论】:

    标签: pandas multi-index


    【解决方案1】:

    更新:

    def add_multicolumn(df, df2, new_col_name):
        tmp = df2.copy()    # make copy, otherwise df2 will be changed !!!
        tmp.columns = pd.MultiIndex.from_product([[new_col_name], df2.columns.tolist()])
        return pd.concat([df, tmp], axis=1)
    

    假设我们有以下 DF,并且我们想要添加第三个“多列”-C

    In [114]: d
    Out[114]:
       A        B
       a  b  c  a  b  c
    0  5  5  7  0  7  2
    1  5  3  9  0  5  5
    2  5  8  5  5  5  7
    3  5  4  5  4  5  2
    

    使用我们的函数:

    In [132]: add_multicolumn(d, d2, 'C')
    Out[132]:
       A        B        C
       a  b  c  a  b  c  a  b  c
    0  5  5  7  0  7  2  0  7  2
    1  5  3  9  0  5  5  0  5  5
    2  5  8  5  5  5  7  5  5  7
    3  5  4  5  4  5  2  4  5  2
    

    旧答案:

    您可以使用pd.concat()

    In [35]: d = pd.concat({'A':d['A'], 'B':d2}, axis=1)
    
    In [36]: d
    Out[36]:
       A        B
       a  b  c  a  b  c
    0  7  3  9  0  7  2
    1  9  4  5  0  5  5
    2  7  6  1  5  5  7
    3  2  5  7  4  5  2
    

    解释:

    In [37]: d['A']
    Out[37]:
       a  b  c
    0  7  3  9
    1  9  4  5
    2  7  6  1
    3  2  5  7
    
    In [40]: pd.concat({'A':d['A'], 'B':d2}, axis=1)
    Out[40]:
       A        B
       a  b  c  a  b  c
    0  5  5  7  0  7  2
    1  5  3  9  0  5  5
    2  5  8  5  5  5  7
    3  5  4  5  4  5  2
    

    【讨论】:

    • 很好,看起来这可能有效。知道是否有可以执行此操作的 DataFrame 方法(例如 d.some_set_method('B', d2))?
    • 其实我更喜欢旧答案,因为它不需要编写额外的函数。我的意思是问是否已经有 DataFrame 的内置方法,因为这些天它们似乎有很多内置方法可用的功能。
    • @beardc,如果您的 DF 已经有多个多列,旧答案将不允许您添加新的多列。但是您不必使用该功能,您只需为要添加的 DF 准备/设置相应的多列
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 2021-06-01
    • 1970-01-01
    • 2021-10-13
    • 2020-04-25
    相关资源
    最近更新 更多