pandas 如何在多索引中插入缺失行

2guxujil  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(130)

我有一个 Dataframe ,看起来像这样

df = pd.DataFrame({'year':[23,23,23,23,23,23], 'month':[1,1,1,2,3,3], 'utility':['A','A','B','A','A','B'], 'state':['NY','NJ','CA','NJ','NY','CA']})

   year  month utility state
0    23      1       A    NY
1    23      1       A    NJ
2    23      1       B    CA
3    23      2       A    NJ
4    23      3       A    NY
5    23      3       B    CA

我还想为缺少月份的公用事业-状态组合创建新行。因此,新 Dataframe 将如下所示

year  month utility state
0    23      1       A    NY
1    23      1       A    NJ
2    23      1       B    CA
3    23      2       A    NY
4    23      2       A    NJ
5    23      2       B    CA
6    23      3       A    NY
7    23      3       A    NJ
8    23      3       B    CA

我知道我可以use a MultiIndex and then reindex,但是使用from_product()方法会导致在原始df中不存在实用程序-状态组合(例如,我不需要实用程序A-CA组合)。
我考虑过将utility和state列连接起来,然后从中得到笛卡尔积,但我认为一定有更简单的方法。

fzwojiic

fzwojiic1#

一个选项是从pyjanitor中使用DataFrame.complete。对于您的数据,您基本上是将(year,month)和(utility,state)组合在一起:

# pip install pyjanitor
import janitor 
    ​
df.complete(('year', 'month'), ('utility', 'state'))
   year  month utility state
0    23      1       A    NY
1    23      1       A    NJ
2    23      1       B    CA
3    23      2       A    NY
4    23      2       A    NJ
5    23      2       B    CA
6    23      3       A    NY
7    23      3       A    NJ
8    23      3       B    CA

@Timeless,恢复你的代码,我会删除我的。你有一个很好的开始,我编辑了你的代码,使它更简单。

1tu0hz3e

1tu0hz3e2#

可能的解决方案:

cols = ['utility', 'state']
d1 = df.drop_duplicates(cols)
d2 = df.drop_duplicates(['year', 'month'])

d2.assign(**{x: [d1[x].to_list()] * len(d2) for x in cols}).explode(cols)

输出:

year  month utility state
0    23      1       A    NY
0    23      1       A    NJ
0    23      1       B    CA
3    23      2       A    NY
3    23      2       A    NJ
3    23      2       B    CA
4    23      3       A    NY
4    23      3       A    NJ
4    23      3       B    CA

我想知道使用numpy broadcasting的解决方案是否可行,它是:

cols1, cols2 = ['year', 'month'], ['utility', 'state']

(pd.DataFrame(
    np.vstack(np.concatenate(
        np.broadcast_arrays(
            df[cols1].drop_duplicates(cols1).values[:,None], 
            df[cols2].drop_duplicates(cols2).values), axis=2)),
    columns=df.columns))

相关问题