【问题标题】:Interweave a dataframe with 0-columns用 0 列交织数据框
【发布时间】:2017-09-15 07:20:40
【问题描述】:

数据:

   A    B
0  a    d
1  b  NaN
2  c    c
3  d    f

如何在 A 和 B 之间交错 0 列?我想得到:

   A  X    B
0  a  0    d
1  b  0  NaN
2  c  0    c
3  d  0    f

同样,对于这个:

   A    B   C
0  a    d   e
1  b  NaN   a
2  c    c   f
3  d    f   g

我想要:

   A  X    B    X    C
0  a  0    d    0    e
1  b  0  NaN    0    a
2  c  0    c    0    f
3  d  0    f    0    g

我该怎么做?

您可以在下面找到我的尝试。我想知道其他可能更短/更有效/古怪的方法。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    1) 一种构造列的方法

    In [916]: df.reindex(columns=sum([[c, 'X'] for c in df.columns], [])[:-1], fill_value=0)
    Out[916]:
       A  X    B  X  C
    0  a  0    d  0  e
    1  b  0  NaN  0  a
    2  c  0    c  0  f
    3  d  0    f  0  g
    
    In [917]: sum([[c, 'X'] for c in df.columns], [])[:-1]
    Out[917]: ['A', 'X', 'B', 'X', 'C']
    

    2)另一种构造方式

    In [924]: def mixcols(cols):
         ...:     ncols = ['X'] * 2 * len(cols)
         ...:     ncols[0::2] = cols
         ...:     return ncols[:-1]
    
    In [925]: mixcols(df.columns)
    Out[925]: ['A', 'X', 'B', 'X', 'C']
    
    In [926]: df.reindex(columns=mixcols(df.columns), fill_value=0)
    Out[926]:
       A  X    B  X  C
    0  a  0    d  0  e
    1  b  0  NaN  0  a
    2  c  0    c  0  f
    3  d  0    f  0  g
    

    3)灵感来自@piR

    In [944]: [c for cx in zip(df.columns, ['X']*len(df.columns)*2) for c in cx][:-1]
    Out[944]: ['A', 'X', 'B', 'X', 'C']
    

    还有,

    In [939]: from itertools import chain, izip
    
    In [940]: list(chain.from_iterable(izip(df.columns, ['X']*len(df.columns)*2)))[:-1]
    Out[940]: ['A', 'X', 'B', 'X', 'C']
    

    4)不推荐的方式

    In [935]: '-|-X-|-'.join(df.columns).split('-|-')
    Out[935]: ['A', 'X', 'B', 'X', 'C']
    

    【讨论】:

    • 为什么4) 不是推荐的方式?
    • 如果你能保证现有的列名不包含 split delim -|- 那么,没关系,但你不能总是这样。
    • TBH +1 是第四个选项。
    【解决方案2】:

    选项 0

    df.reindex_axis([x for y in lst for x in [y, 'X']][:-1], 1, fill_value=0)
    
       A  X    B  X  C
    0  a  0    d  0  e
    1  b  0  NaN  0  a
    2  c  0    c  0  f
    3  d  0    f  0  g
    

    选项 1
    字符串黑客
    实际上,@John Galt 击败了我。

    df.reindex_axis('|X|'.join(df).split('|'), 1, fill_value=0)
    
       A  X    B  X  C
    0  a  0    d  0  e
    1  b  0  NaN  0  a
    2  c  0    c  0  f
    3  d  0    f  0  g
    

    选项 2
    使用cytoolz.interleave
    @root here 学习

    from cytoolz import interleave
    
    df.reindex(
        columns=list(interleave([df, list('X' * (df.shape[1] - 1))])),
        fill_value=0)
    
       A  X    B  X  C
    0  a  0    d  0  e
    1  b  0  NaN  0  a
    2  c  0    c  0  f
    3  d  0    f  0  g
    

    【讨论】:

    • 这是一个 hack,@cᴏʟᴅsᴘᴇᴇᴅ 是 OP,所以他很聪明,可以弄清楚 (-:
    【解决方案3】:

    我尝试使用df.reindex 解决方案:

    def foo(cols):
         yield cols[0]
         for c in cols[1:]:
             yield from ('X', c)
    
    df1.reindex(columns=foo(df1.columns), fill_value=0)
    
       A  X    B
    0  a  0    d
    1  b  0  NaN
    2  c  0    c
    3  d  0    f
    

    【讨论】:

      猜你喜欢
      • 2020-11-20
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 2012-07-17
      相关资源
      最近更新 更多