向数据帧中添加列表,同时按DF的长度合并

2024-10-05 14:30:25 发布

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

无法找到解决办法,所以道歉,如果这似乎很简单。你知道吗

我有一个df如下:

ID, Week
5, 1
6, 1
7, 1

我有一个原因代码清单如下

['Work', 'Holiday', 'Sick', 'Jury'] 

我要做的是把它加到我当前的数据帧中,然后乘以每个唯一的ID

所以我会有这样的东西(为了简洁起见,我只使用一个唯一的ID)

ID, Week, Reason
5,  1,    'Work'
5,  1,    'Holiday'
5,  1,    'Sick',
5,  1,    'Jury'

我尝试过各种各样的concats,不同的轴,但我不知道如何处理这个。你知道吗

任何帮助都将不胜感激。你知道吗


Tags: 数据代码iddf原因workreasonweek
3条回答

codes成为原因列表

codes = ['Work', 'Holiday', 'Sick', 'Jury']

为数据框的所有行分配相同的代码。RHS上的语法只是将列表复制N次,其中N是数据帧的长度

df['codes'] = [codes] * len(df)

然后堆叠codes列,即从水平格式更改为垂直格式。在此步骤中,还需要将ID&;Week列设置为索引,然后在堆栈操作完成后重置它们。你知道吗

df.set_index(['ID','Week']).codes.apply(pd.Series).stack().reset_index(['ID', 'Week'])

输出:

   ID  Week        0
0   5     1     Work
1   5     1  Holiday
2   5     1     Sick
3   5     1     Jury
0   6     1     Work
1   6     1  Holiday
2   6     1     Sick
3   6     1     Jury
0   7     1     Work
1   7     1  Holiday
2   7     1     Sick
3   7     1     Jury

剩下的唯一一件事就是为新创建的列指定一个合适的名称,如果代码依赖于索引值,请适当地修复它。在这个版本中,索引值是从原始数据帧继承下来的&重复四次

让我们做unnesting

df['Reason']=[l]*len(df)
unnesting(df,['Reason'])
Out[1014]: 
    Reason  ID  Week
0     Work   5     1
0  Holiday   5     1
0     Sick   5     1
0     Jury   5     1
1     Work   6     1
1  Holiday   6     1
1     Sick   6     1
1     Jury   6     1
2     Work   7     1
2  Holiday   7     1
2     Sick   7     1
2     Jury   7     1

# attached self-define function
def unnesting(df, explode):
    idx=df.index.repeat(df[explode[0]].str.len())
    df1=pd.concat([pd.DataFrame({x:np.concatenate(df[x].values)} )for x in explode],axis=1)
    df1.index=idx
    return df1.join(df.drop(explode,1),how='left')

或者我们交叉连接

df.merge(pd.DataFrame({'Reason':l}).assign(Week=1))
Out[1020]: 
    ID  Week   Reason
0    5     1     Work
1    5     1  Holiday
2    5     1     Sick
3    5     1     Jury
4    6     1     Work
5    6     1  Holiday
6    6     1     Sick
7    6     1     Jury
8    7     1     Work
9    7     1  Holiday
10   7     1     Sick
11   7     1     Jury

您可以使用itertools来实现:

import itertools
df_new=(pd.DataFrame(list(itertools.product(df.ID,df.Week,reason_codes)),
    columns=df.columns.tolist()+['Reason']).drop_duplicates().reset_index(drop=True))
print(df_new)

    ID  Week   Reason
0    5     1     Work
1    5     1  Holiday
2    5     1     Sick
3    5     1     Jury
4    6     1     Work
5    6     1  Holiday
6    6     1     Sick
7    6     1     Jury
8    7     1     Work
9    7     1  Holiday
10   7     1     Sick
11   7     1     Jury

相关问题 更多 >