【问题标题】:Pandas Dynamic Stack熊猫动态堆栈
【发布时间】:2016-03-15 20:55:58
【问题描述】:

给定以下数据框:

import numpy as np
import pandas as pd

df = pd.DataFrame({'foo':['a','b','c','d'],
                   'bar':['e','f','g','h'],
                       0:['i','j','k',np.nan],
                       1:['m',np.nan,'o','p']})
df=df[['foo','bar',0,1]]
df

    foo   bar    0      1
0   a     e      i      m
1   b     f      j     NaN
2   c     g      k      o
3   d     h     NaN     p

...这是由产生列 01 的先前过程产生的(并且可能产生比 01 更多或更少的列,具体取决于数据): 我想以某种方式堆叠(如果这是正确的术语)数据,以便01 的每个值(忽略NaNs)产生一个像这样的新行:

    foo bar
0   a   e
0   a   i
0   a   m
1   b   f
1   b   j
2   c   g
2   c   k
2   c   o
3   d   h
3   d   p

您可能注意到公共字段是foo。 在我的实际数据集中可能会出现更多常见字段。 另外,我不确定索引值在foo 的值之间重复的最终结果有多重要。只要数据正确,这就是我主要关心的问题。

更新: 如果我有 2+ 个这样的常见字段怎么办:

import numpy as np
import pandas as pd

df = pd.DataFrame({'foo':['a','a','b','b'],
                   'foo2':['a2','b2','c2','d2'],
                   'bar':['e','f','g','h'],
                       0:['i','j','k',np.nan],
                       1:['m',np.nan,'o','p']})
df=df[['foo','foo2','bar',0,1]]
df

    foo     foo2    bar     0   1
0   a       a2      e     i     m
1   a       b2      f     j     NaN
2   b       c2      g     k     o
3   b       d2      h     NaN   p

【问题讨论】:

    标签: python-3.x pandas pivot dataframe


    【解决方案1】:

    您可以使用set_indexstackreset_index

    print df.set_index('foo').stack().reset_index(level=1, drop=True).reset_index(name='bar')
      foo bar
    0   a   e
    1   a   i
    2   a   m
    3   b   f
    4   b   j
    5   c   g
    6   c   k
    7   c   o
    8   d   h
    9   d   p
    

    如果需要索引,请使用melt:

    print pd.melt(df.reset_index(), 
                  id_vars=['index', 'foo'], 
                  value_vars=['bar', 0, 1],
                  value_name='bar')
            .sort_values('index')
            .set_index('index', drop=True)
            .dropna()
            .drop('variable', axis=1)
            .rename_axis(None)
    
      foo bar
    0   a   e
    0   a   i
    0   a   m
    1   b   f
    1   b   j
    2   c   g
    2   c   k
    2   c   o
    3   d   h
    3   d   p
    

    或者使用不知名的lreshape

    print pd.lreshape(df.reset_index(), {'bar': ['bar', 0, 1]})
            .sort_values('index')
            .set_index('index', drop=True)
            .rename_axis(None)
    
      foo bar
    0   a   e
    0   a   i
    0   a   m
    1   b   f
    1   b   j
    2   c   g
    2   c   k
    2   c   o
    3   d   h
    3   d   p
    

    【讨论】:

    • 你太棒了!你是怎么知道这些东西的?
    • Index 重要吗?或者您可以使用类似于stack 的第一个解决方案?
    • 索引不重要。我都试过这样但没有骰子: print (df.set_index('foo','foo2').stack().reset_index(level=1, drop=True).reset_index(name='bar'))跨度>
    • 现在我明白了,我必须像这样将 reset_index 上的级别值调整为 2: print (df.set_index(['foo','foo2']).stack().reset_index( level=2, drop=True).reset_index(name='bar'))
    • 抱歉,我认为您需要将列 foofoo2 合并为一个 :) - 可以通过 print df.set_index(['foo', 'foo2']).stack().reset_index(level=2, drop=True).reset_index(name='bar').set_index('bar').stack().reset_index(level=1, drop=True).reset_index(name='foo')
    猜你喜欢
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 2019-06-19
    • 2021-10-05
    • 2023-01-11
    • 2019-05-17
    • 2020-07-26
    相关资源
    最近更新 更多