【问题标题】:How do I convert a MultiIndex to type string如何将 MultiIndex 转换为类型字符串
【发布时间】:2016-12-30 21:11:18
【问题描述】:

考虑 MultiIndex idx

idx = pd.MultiIndex.from_product([range(2013, 2016), range(1, 5)])

当我这样做时

idx.to_series().str.join(' ')

我明白了

2013  1   NaN
      2   NaN
      3   NaN
      4   NaN
2014  1   NaN
      2   NaN
      3   NaN
      4   NaN
2015  1   NaN
      2   NaN
      3   NaN
      4   NaN
dtype: float64

发生这种情况是因为不同级别的 dtype 是 int 而不是 strjoin 需要 str。如何将整个idx 转换为str

我已经完成了

join = lambda x, delim=' ': delim.join([str(y) for y in x])
idx.to_series().apply(join, delim=' ')

2013  1    2013 1
      2    2013 2
      3    2013 3
      4    2013 4
2014  1    2014 1
      2    2014 2
      3    2014 3
      4    2014 4
2015  1    2015 1
      2    2015 2
      3    2015 3
      4    2015 4
dtype: object

我希望有一种更简单的方法可以忽略。

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    我不确定这是最优雅的方式,但它应该可以工作:

    idx.get_level_values(0).astype(str).values + ' ' + idx.get_level_values(1).astype(str).values
    

    【讨论】:

    • 这与我的意图最接近。
    【解决方案2】:

    这样的?

    idx.to_series().apply(lambda x: '{0}-{1}'.format(*x))
    

    【讨论】:

    • 这与我已经完成的非常相似。但我喜欢它。
    • @piRSquared 对,我没有意识到你想要一个列表。您可以将.values 附加到上面的行以获得与接受的答案相同的输出。
    • 在下面查看我的答案。我想要一种有效而优雅的方式将索引转换为 dtype str
    【解决方案3】:

    使用来自itertoolsstarmap 的通用解决方案

    from itertools import starmap
    
    def flat2(midx, sep=''):
        fstr = sep.join(['{}'] * midx.nlevels)
        return pd.Index(starmap(fstr.format, midx))
    

    演示

    midx = pd.MultiIndex.from_product([[1, 2], [3, 4]])
    

    flat(midx)
    Index([u'13', u'14', u'23', u'24'], dtype='object')
    

    flat(midx, '_')
    Index([u'1_3', u'1_4', u'2_3', u'2_4'], dtype='object')
    

    【讨论】:

      【解决方案4】:

      最快的是列表推导:

      print (['{} {}'.format(i[1], i[0]) for i in idx])
      print ([' '.join((str(i[0]), str(i[1]))) for i in idx])
      

      时间安排

      In [21]: %timeit (['{} {}'.format(i[1], i[0]) for i in idx])
      The slowest run took 4.68 times longer than the fastest. This could mean that an intermediate result is being cached.
      100000 loops, best of 3: 7.51 µs per loop
      
      In [22]: %timeit ([' '.join((str(i[0]), str(i[1]))) for i in idx])
      The slowest run took 6.48 times longer than the fastest. This could mean that an intermediate result is being cached.
      100000 loops, best of 3: 9.62 µs per loop
      
      In [23]: %timeit (idx.get_level_values(0).astype(str).values + ' ' + idx.get_level_values(1).astype(str).values)
      The slowest run took 5.91 times longer than the fastest. This could mean that an intermediate result is being cached.
      1000 loops, best of 3: 215 µs per loop
      
      In [24]: %timeit idx.to_series().apply(lambda x: '{0}-{1}'.format(*x))
      The slowest run took 5.43 times longer than the fastest. This could mean that an intermediate result is being cached.
      1000 loops, best of 3: 369 µs per loop
      
      In [25]: %timeit idx.to_series().str.join(' ')
      The slowest run took 5.53 times longer than the fastest. This could mean that an intermediate result is being cached.
      1000 loops, best of 3: 394 µs per loop
      

      【讨论】:

        猜你喜欢
        • 2012-09-19
        • 1970-01-01
        • 2022-08-18
        • 2019-09-10
        • 1970-01-01
        • 2019-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多