即使数据中没有值,也要创建其他行

2024-09-28 18:55:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个如下所示的数据帧:

Person  Day  Value
 1      Mon   32
 1      Tue   30
 1      Wed   34
 1      Thu   22
 1      Fri   43
 2      Mon   22
 2      Wed   14
 2      Fri   11
 3      Tue   13
 3      Wed   22
 3      Thu   23

数据集查看一组人的每个工作日(周一至周五)的值。有些人有完整的5天(例如,人1),有些人只有几天。我想创建新的空行,这样每个人都有完整的5天,即使他们没有值

这是我想要的输出:

Person  Day  Value
 1      Mon   32
 1      Tue   30
 1      Wed   34
 1      Thu   22
 1      Fri   43
 2      Mon   22
 2      Tue   Nan
 2      Wed   14
 2      Thu   Nan
 2      Fri   11
 3      Mon   Nan
 3      Tue   13
 3      Wed   22
 3      Thu   23
 3      Fri   Nan

我试着写了一些东西,但我不知道如何让它正确地遍历每个人:

days = ['mon','tue','wed','thu','fri']


def normalise(person):
    newperson = pd.DataFrame()
    for day in days:
        if day in person:
            newperson[day] = days
        else:
            newperson[day] = np.nan
    return newperson

normalised = normalise(df)

这只生成天数,但不包含其他值。 实际数据集大约有200000人。 任何想法都很好,谢谢


Tags: 数据valuenandayspersondaymonwed
2条回答

unstackstack返回dropna=False

days = ['Mon','Tue','Wed','Thu','Fri']

out = (df.set_index(['Person','Day'])['Value'].unstack()
         .reindex(days ,axis=1)
         .stack(dropna=False).reset_index(name='Value'))

    Person  Day  Value
0        1  Mon   32.0
1        1  Tue   30.0
2        1  Wed   34.0
3        1  Thu   22.0
4        1  Fri   43.0
5        2  Mon   22.0
6        2  Tue    NaN
7        2  Wed   14.0
8        2  Thu    NaN
9        2  Fri   11.0
10       3  Mon    NaN
11       3  Tue   13.0
12       3  Wed   22.0
13       3  Thu   23.0
14       3  Fri    NaN

@anky的解决方案很棒;我将推荐一种替代方法,它可以方便地抽象解决方案(特别是对于非唯一索引和空值)

可以使用pyjanitor中的complete函数公开显式缺少的值:

# pip install janitor
import pandas as pd
import numpy as np
import janitor

In [5]: df.complete(['Person', 'Day'])
Out[5]: 
    Person  Day  Value
0        1  Fri   43.0
1        1  Mon   32.0
2        1  Thu   22.0
3        1  Tue   30.0
4        1  Wed   34.0
5        2  Fri   11.0
6        2  Mon   22.0
7        2  Thu    NaN
8        2  Tue    NaN
9        2  Wed   14.0
10       3  Fri    NaN
11       3  Mon    NaN
12       3  Thu   23.0
13       3  Tue   13.0
14       3  Wed   22.0

如果要保持日的顺序,可以将“日”列转换为分类类型:

In [7]: (df.astype({"Day":pd.api.types.CategoricalDtype(categories=df.Day.unique(), 
                                                        ordered=True)})
           .complete(['Person', 'Day']))
Out[7]: 
    Person  Day  Value
0        1  Mon   32.0
1        1  Tue   30.0
2        1  Wed   34.0
3        1  Thu   22.0
4        1  Fri   43.0
5        2  Mon   22.0
6        2  Tue    NaN
7        2  Wed   14.0
8        2  Thu    NaN
9        2  Fri   11.0
10       3  Mon    NaN
11       3  Tue   13.0
12       3  Wed   22.0
13       3  Thu   23.0
14       3  Fri    NaN

相关问题 更多 >