Python 将列表添加到数据帧,同时按DF的长度合并
无法找到解决方案,因此,如果这看起来很简单,请道歉 我的df如下所示:Python 将列表添加到数据帧,同时按DF的长度合并,python,pandas,Python,Pandas,无法找到解决方案,因此,如果这看起来很简单,请道歉 我的df如下所示: ID, Week 5, 1 6, 1 7, 1 我有一个原因代码列表如下 ['Work', 'Holiday', 'Sick', 'Jury'] 我要做的是将它添加到我当前的数据帧中,但将它乘以每个唯一的ID 所以我会有这样的想法(为了简洁起见,我只使用一个唯一的ID) 我已经尝试过各种各样的concats,有各种不同的axis,但我一点也不知道如何实现这一点 非常感谢您的帮助。您可以使用itertools来实现以下目
ID, Week
5, 1
6, 1
7, 1
我有一个原因代码列表如下
['Work', 'Holiday', 'Sick', 'Jury']
我要做的是将它添加到我当前的数据帧中,但将它乘以每个唯一的ID
所以我会有这样的想法(为了简洁起见,我只使用一个唯一的ID)
我已经尝试过各种各样的concats,有各种不同的axis,但我一点也不知道如何实现这一点
非常感谢您的帮助。您可以使用
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
您可以为此使用
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
让
code
作为原因列表
codes = ['Work', 'Holiday', 'Sick', 'Jury']
为数据框的所有行指定相同的代码。RHS上的语法只是将列表复制N次,其中N是数据帧的长度
df['codes'] = [codes] * len(df)
然后堆叠代码
列,即从水平格式更改为垂直格式。在此步骤中,还需要将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
剩下的唯一一件事就是为新创建的列指定一个合适的名称,如果代码依赖于索引值,请适当地修复它。在这个版本中,索引值是从原始数据帧中带入的,并重复四次让
代码
作为原因列表
codes = ['Work', 'Holiday', 'Sick', 'Jury']
为数据框的所有行指定相同的代码。RHS上的语法只是将列表复制N次,其中N是数据帧的长度
df['codes'] = [codes] * len(df)
然后堆叠代码
列,即从水平格式更改为垂直格式。在此步骤中,还需要将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
剩下的唯一一件事就是为新创建的列指定一个合适的名称,如果代码依赖于索引值,请适当地修复它。在这个版本中,索引值是从原始数据帧中带入的&重复四次
或者我们交叉连接
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
让我们做吧
或者我们交叉连接
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
我认为您只需要从中创建一个数据帧
df_codes = pd.DataFrame({'codes': ['Work', 'Holiday', 'Sick', 'Jury']})
在这之后,您只需要像在这个线程中那样在没有公共列的情况下交叉连接数据帧
基于该线程,在创建df_code
之后,您只需要以下命令:
df_new = df.assign(a=1).merge(df_codes.assign(a=1)).drop('a', 1)
输出:
Out[148]:
ID Week codes
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
我认为您只需要从中创建一个数据帧
df_codes = pd.DataFrame({'codes': ['Work', 'Holiday', 'Sick', 'Jury']})
在这之后,您只需要像在这个线程中那样在没有公共列的情况下交叉连接数据帧
基于该线程,在创建df_code
之后,您只需要以下命令:
df_new = df.assign(a=1).merge(df_codes.assign(a=1)).drop('a', 1)
输出:
Out[148]:
ID Week codes
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
我很清楚,你希望
工作
,假期
,生病
,陪审团
会对所有ID
,周
组合重复?现在就知道了,但如果你能发布两种解决方案,那就太棒了,我很清楚了,你希望工作
,假期
,生病
,Jury
对于所有的ID
,周
组合都要重复吗?现在只需要ID,但如果你能发布两种解决方案,那就是greatThanks Haleemur,这就完美了!我真的很喜欢stack的方法,谢谢。谢谢Haleemur,这非常有效!我真的很喜欢stack的方法,谢谢。谢谢这篇文章,非常喜欢你的自定义函数好的先生。@DataNoveler yw:-)快乐编码:-)谢谢这篇文章,非常喜欢你的自定义函数好的先生。@DataNoveler yw:-)快乐编码:-)谢谢Andy,我确实看到了你的第一个评论,但我认为温家宝的第二个解决方案是在多种情况下最具可读性和易用性的。谢谢你的解决方案,我真的需要多练习!如果我的假设有误,请让我知道。@datanoveler这很好。:)没问题。:)谢谢你的投票。谢谢安迪,我确实看到了你的第一个评论,但我认为温家宝的第二个解决方案是最具可读性的,并且在很多情况下都很容易使用。谢谢你的解决方案,我真的需要多练习!如果我的假设有误,请让我知道。@datanoveler这很好。:)没问题。:)谢谢你的投票。