Python 为回归平衡面板数据

Python 为回归平衡面板数据,python,pandas,dataframe,panel,Python,Pandas,Dataframe,Panel,我有一个数据帧: df = pd.DataFrame({"id": [1, 1, 1, 2, 2, 3], "city": ['abc', 'abc', 'abc', 'def10', 'def10', 'ghk'] ,"year": [2008, 2009, 2010, 2008, 2010,2009], "value": [10,20,30,10,20,30]}) df = pd.DataFrame({&qu

我有一个数据帧:

df = pd.DataFrame({"id": [1, 1, 1, 2, 2, 3], "city": ['abc', 'abc', 'abc', 'def10', 'def10', 'ghk'] ,"year": [2008, 2009, 2010, 2008, 2010,2009], "value": [10,20,30,10,20,30]})

df = pd.DataFrame({"id": [1,1,1,2,2,3,3], "city": ['abc','abc','abc','def10','def10','ghk','ghk'], "year": [2008,2009,2010,2008,2010,2009,2009], "value": [10,20,30,10,20,30,40]})
我想创建一个平衡的数据,以便:

    id  city     year  value
0   1    abc    2008    10 
1   1    abc    2009    20
2   1    abc    2010    30
3   2   def10   2008    10
4   2   def10   2009    NaN
5   2   def10   2010    20
6   3   ghk     2008    NaN
7   3   ghk     2009    30
8   3   ghk     2009    NaN

如果我使用以下代码:

df = df.set_index('id')
balanced = (id.set_index('year',append=True).reindex(pd.MultiIndex.from_product([df.index,range(df.year.min(),df.year.max()+1)],names=['frs_id','year'])).reset_index(level=1))

这给了我以下错误:

cannot handle a non-unique multi-index!

透视表和堆栈
year
,不带下拉NaN值:

>>> df.pivot(["id", "city"], "year", "value") \
      .stack(dropna=False) \
      .rename("value") \
      .reset_index()

   id   city  year  value
0   1    abc  2008   10.0
1   1    abc  2009   20.0
2   1    abc  2010   30.0
3   2  def10  2008   10.0
4   2  def10  2009    NaN
5   2  def10  2010   20.0
6   3    ghk  2008    NaN
7   3    ghk  2009   30.0
8   3    ghk  2010    NaN
编辑:重复条目的情况

我稍微修改了您的原始数据帧:

df = pd.DataFrame({"id": [1, 1, 1, 2, 2, 3], "city": ['abc', 'abc', 'abc', 'def10', 'def10', 'ghk'] ,"year": [2008, 2009, 2010, 2008, 2010,2009], "value": [10,20,30,10,20,30]})

df = pd.DataFrame({"id": [1,1,1,2,2,3,3], "city": ['abc','abc','abc','def10','def10','ghk','ghk'], "year": [2008,2009,2010,2008,2010,2009,2009], "value": [10,20,30,10,20,30,40]})
你需要做出决定。您想保留第5行还是第6行,还是应用数学函数(平均值、总和……)。想象一下你想要(3,ghk,2009)的平均值:

df.pivot_表(索引=[“id”,“city”],columns=“year”,values=“value”,aggfunc=“mean”)\ .stack(dropna=False)\ .重命名(“值”)\ .reset_index() id城市年份值 01 abc 2008 10.0 1 1 abc 2009 20.0 2.1 abc 2010 30.0 3.2 def10 2008 10.0 4.2 2009年12月10日NaN 5.2 def10 2010 20.0 6.3 ghk 2008 NaN
7.3 ghk 2009 35.0#透视表和堆栈
无下降值:

>>> df.pivot(["id", "city"], "year", "value") \
      .stack(dropna=False) \
      .rename("value") \
      .reset_index()

   id   city  year  value
0   1    abc  2008   10.0
1   1    abc  2009   20.0
2   1    abc  2010   30.0
3   2  def10  2008   10.0
4   2  def10  2009    NaN
5   2  def10  2010   20.0
6   3    ghk  2008    NaN
7   3    ghk  2009   30.0
8   3    ghk  2010    NaN
编辑:重复条目的情况

我稍微修改了您的原始数据帧:

df = pd.DataFrame({"id": [1, 1, 1, 2, 2, 3], "city": ['abc', 'abc', 'abc', 'def10', 'def10', 'ghk'] ,"year": [2008, 2009, 2010, 2008, 2010,2009], "value": [10,20,30,10,20,30]})

df = pd.DataFrame({"id": [1,1,1,2,2,3,3], "city": ['abc','abc','abc','def10','def10','ghk','ghk'], "year": [2008,2009,2010,2008,2010,2009,2009], "value": [10,20,30,10,20,30,40]})
你需要做出决定。您想保留第5行还是第6行,还是应用数学函数(平均值、总和……)。想象一下你想要(3,ghk,2009)的平均值:

df.pivot_表(索引=[“id”,“city”],columns=“year”,values=“value”,aggfunc=“mean”)\ .stack(dropna=False)\ .重命名(“值”)\ .reset_index() id城市年份值 01 abc 2008 10.0 1 1 abc 2009 20.0 2.1 abc 2010 30.0 3.2 def10 2008 10.0 4.2 2009年12月10日NaN 5.2 def10 2010 20.0 6.3 ghk 2008 NaN
7 3 ghk 2009 35.0#您已接近解决方案。您可以对代码稍作修改,如下所示:

idx = pd.MultiIndex.from_product([df['id'].unique(),range(df.year.min(),df.year.max()+1)],names=['id','year'])

df2 = df.set_index(['id', 'year']).reindex(idx).reset_index()

df2['city'] = df2.groupby('id')['city'].ffill().bfill()
(df.set_index(['id', 'city', 'year'], append=True)
   .unstack()
   .groupby(level=[1, 2]).max()
   .stack(dropna=False)
).reset_index()
对代码的更改:

  • 使用
    id
    的唯一值而不是从索引创建多索引
  • 在重新索引()之前,在
    id
    year
    上设置索引
  • 通过相同
    id
    的非NaN条目填写
    city
    列的
    NaN
  • 结果:

    print(df2)
    
       id  year   city  value
    0   1  2008    abc   10.0
    1   1  2009    abc   20.0
    2   1  2010    abc   30.0
    3   2  2008  def10   10.0
    4   2  2009  def10    NaN
    5   2  2010  def10   20.0
    6   3  2008    ghk    NaN
    7   3  2009    ghk   30.0
    8   3  2010    ghk    NaN
    
    
    (可选)如果愿意,可以重新排列列序列:

    df2.insert(2, 'year', df2.pop('year'))
    
    编辑 您还可以使用
    stack()
    unstack()
    来执行此操作,而无需使用
    reindex()
    ,如下所示:

    idx = pd.MultiIndex.from_product([df['id'].unique(),range(df.year.min(),df.year.max()+1)],names=['id','year'])
    
    df2 = df.set_index(['id', 'year']).reindex(idx).reset_index()
    
    df2['city'] = df2.groupby('id')['city'].ffill().bfill()
    
    (df.set_index(['id', 'city', 'year'], append=True)
       .unstack()
       .groupby(level=[1, 2]).max()
       .stack(dropna=False)
    ).reset_index()
    
    输出:

       id   city  year  value
    0   1    abc  2008   10.0
    1   1    abc  2009   20.0
    2   1    abc  2010   30.0
    3   2  def10  2008   10.0
    4   2  def10  2009    NaN
    5   2  def10  2010   20.0
    6   3    ghk  2008    NaN
    7   3    ghk  2009   30.0
    8   3    ghk  2010    NaN
    

    您已接近解决方案。您可以对代码稍作修改,如下所示:

    idx = pd.MultiIndex.from_product([df['id'].unique(),range(df.year.min(),df.year.max()+1)],names=['id','year'])
    
    df2 = df.set_index(['id', 'year']).reindex(idx).reset_index()
    
    df2['city'] = df2.groupby('id')['city'].ffill().bfill()
    
    (df.set_index(['id', 'city', 'year'], append=True)
       .unstack()
       .groupby(level=[1, 2]).max()
       .stack(dropna=False)
    ).reset_index()
    
    对代码的更改:

  • 使用
    id
    的唯一值而不是从索引创建多索引
  • 在重新索引()之前,在
    id
    year
    上设置索引
  • 通过相同
    id
    的非NaN条目填写
    city
    列的
    NaN
  • 结果:

    print(df2)
    
       id  year   city  value
    0   1  2008    abc   10.0
    1   1  2009    abc   20.0
    2   1  2010    abc   30.0
    3   2  2008  def10   10.0
    4   2  2009  def10    NaN
    5   2  2010  def10   20.0
    6   3  2008    ghk    NaN
    7   3  2009    ghk   30.0
    8   3  2010    ghk    NaN
    
    
    (可选)如果愿意,可以重新排列列序列:

    df2.insert(2, 'year', df2.pop('year'))
    
    编辑 您还可以使用
    stack()
    unstack()
    来执行此操作,而无需使用
    reindex()
    ,如下所示:

    idx = pd.MultiIndex.from_product([df['id'].unique(),range(df.year.min(),df.year.max()+1)],names=['id','year'])
    
    df2 = df.set_index(['id', 'year']).reindex(idx).reset_index()
    
    df2['city'] = df2.groupby('id')['city'].ffill().bfill()
    
    (df.set_index(['id', 'city', 'year'], append=True)
       .unstack()
       .groupby(level=[1, 2]).max()
       .stack(dropna=False)
    ).reset_index()
    
    输出:

       id   city  year  value
    0   1    abc  2008   10.0
    1   1    abc  2009   20.0
    2   1    abc  2010   30.0
    3   2  def10  2008   10.0
    4   2  def10  2009    NaN
    5   2  def10  2010   20.0
    6   3    ghk  2008    NaN
    7   3    ghk  2009   30.0
    8   3    ghk  2010    NaN
    

    我得到了这样的结论:索引包含重复的条目,无法重塑它对您的示例
    df
    有效。你试过其他数据吗?(你对熊猫的看法是什么?)谢谢你的回复。是的,我的版本是1.2.4。是的,我正在处理另一个大数据以及20多个列。我得到了这样一个信息:索引包含重复的条目,无法重塑。它适用于您的示例
    df
    。你试过其他数据吗?(你对熊猫的看法是什么?)谢谢你的回复。是的,我的版本是1.2.4。是的,我正在研究另一个大数据以及20多列