如何在熊猫数据框的行之间应用多个条件创建目标数据框
Posted
技术标签:
【中文标题】如何在熊猫数据框的行之间应用多个条件创建目标数据框【英文标题】:How to creat a target dataframe applying multiple condition between the rows of a panda dataframe 【发布时间】:2021-12-05 22:42:36 【问题描述】:我问下面的问题,因为我没有找到任何合适的答案,基于 data-frame
的 different rows
上的 multiple condition
应用。
我有下面的data-frame
我想在其rows
上应用multiple condition
以创建一个新的data-frame
timestamp t_id b_id id b_sent lc
0 6/1/2020 9:00 25 1 C_0 25 540
1 6/1/2020 9:00 25 1 C_1 25 540
2 6/1/2020 9:00 25 1 C_2 25 540
3 6/1/2020 9:00 25 1 C_3 28 478
4 6/1/2020 9:00 25 1 V_0 25 NA
5 6/1/2020 9:00 25 1 V_1 25 NA
6 6/1/2020 9:00 25 1 V_2 25 NA
7 6/1/2020 9:00 25 1 V_3 91 NA
8 6/1/2020 9:00 25 2 C_0 26 510
9 6/1/2020 9:00 25 2 C_1 26 510
10 6/1/2020 9:00 25 2 C_2 27 510
11 6/1/2020 9:00 25 2 C_3 32 300
12 6/1/2020 9:00 25 2 V_0 26 NA
13 6/1/2020 9:00 25 2 V_1 26 NA
14 6/1/2020 9:00 25 2 V_2 26 NA
15 6/1/2020 9:00 25 2 V_3 26 NA
16 6/1/2020 9:30 25 1 C_0 10 140
17 6/1/2020 9:30 25 1 C_1 20 340
18 6/1/2020 9:30 25 1 C_2 25 240
19 6/1/2020 9:30 25 1 C_3 30 578
20 6/1/2020 9:30 25 1 V_0 25 NA
21 6/1/2020 9:30 25 1 V_1 25 NA
22 6/1/2020 9:30 25 1 V_2 25 NA
23 6/1/2020 9:30 25 1 V_3 91 NA
24 6/1/2020 9:30 25 2 C_0 15 140
25 6/1/2020 9:30 25 2 C_1 20 340
26 6/1/2020 9:30 25 2 C_2 35 240
27 6/1/2020 9:30 25 2 C_3 40 578
28 6/1/2020 9:30 25 2 V_0 25 NA
29 6/1/2020 9:30 25 2 V_1 35 NA
30 6/1/2020 9:30 25 2 V_2 45 NA
31 6/1/2020 9:30 25 2 V_3 25 NA
输出将基于以下条件,timestamps
应该相同:
b_sent_new = b_sent(b_id==1,id=='C_0') + b_sent(b_id==2,id=='V_0')
b_sent_new = b_sent(b_id==1,id=='C_1') + b_sent(b_id==2,id=='V_1')
b_sent_new = b_sent(b_id==1,id=='C_2') + b_sent(b_id==2,id=='V_2')
b_sent_new = b_sent(b_id==1,id=='C_3') + b_sent(b_id==2,id=='V_3')
and vice verca
b_sent_new = b_sent(b_id==2,id=='C_0') + b_sent(b_id==1,id=='V_0')
b_sent_new = b_sent(b_id==2,id=='C_1') + b_sent(b_id==1,id=='V_1')
b_sent_new = b_sent(b_id==2,id=='C_2') + b_sent(b_id==1,id=='V_2')
b_sent_new = b_sent(b_id==2,id=='C_3') + b_sent(b_id==1,id=='V_3')
例如,b_sent_new
值将是 b_sent
值,其中 b_id=1
和 id=C_0
加上 b_sent
值,其中 b_id=2
和 id=V_0
在同一“时间戳”内
更准确地说,对于b_id
值1,对应C_0
的b_sent_new
值将是b_id
的C_0
的b_sent
值加上1
的1
的b_sent
值b_id
2
想要的输出:
timestamp t_id b_id id b_sent lc b_sent_new
0 6/1/2020 9:00 25 1 C_0 25 540 51
1 6/1/2020 9:00 25 1 C_1 26 540 53
2 6/1/2020 9:00 25 1 C_2 22 540 50
3 6/1/2020 9:00 25 1 C_3 28 478 47
4 6/1/2020 9:00 25 2 C_0 30 510 48
5 6/1/2020 9:00 25 2 C_1 31 510 47
6 6/1/2020 9:00 25 2 C_2 32 510 49
7 6/1/2020 9:00 25 2 C_3 33 300 51
8 6/1/2020 9:30 25 1 C_0 10 140 35
9 6/1/2020 9:30 25 1 C_1 20 340 55
10 6/1/2020 9:30 25 1 C_2 25 240 70
11 6/1/2020 9:30 25 1 C_3 30 578 55
12 6/1/2020 9:30 25 2 C_0 15 140 40
13 6/1/2020 9:30 25 2 C_1 20 340 45
14 6/1/2020 9:30 25 2 C_2 35 240 60
15 6/1/2020 9:30 25 2 C_3 40 578 131
我目前遵循的方法没有给我适当的输出:
box_1 = df[df.b_id.isin(["1"])].reset_index(drop = True)
box_2 = df[df.b_id.isin(["2"])].reset_index(drop = True)
box_1['new'] = np.where((box_1['timestamp'] == box_2['timestamp'] ) & (box_1['id']=="C_0") & (box_2['id'].shift(-4)=="V_0"), box_1['b_sent']+box_2['b_sent'].shift(-4), np.nan)
box_1['new'] = np.where((box_1['timestamp'] == box_2['timestamp'] ) & (box_1['id']=="C_1") & (box_2['id'].shift(-4)=="V_1"), box_1['b_sent']+box_2['b_sent'].shift(-4), np.nan)
box_1['new'] = np.where((box_1['timestamp'] == box_2['timestamp'] ) & (box_1['id']=="C_2") & (box_2['id'].shift(-4)=="V_2"), box_1['b_sent']+box_2['b_sent'].shift(-4), np.nan)
box_1['new'] = np.where((box_1['timestamp'] == box_2['timestamp'] ) & (box_1['id']=="C_3") & (box_2['id'].shift(-4)=="V_3"), box_1['b_sent']+box_2['b_sent'].shift(-4), np.nan)
任何帮助/建议将不胜感激。
【问题讨论】:
请多解释一下逻辑,并按原样添加最终数据帧,不要使用 cmets @sammywemmy 解释了逻辑并编辑了输出,希望这会更清楚。 【参考方案1】:可能有更友好的方式来执行此操作,但这应该可以帮助您入门。它创建了一个更广泛的数据框,您必须对其进行修改以满足您的需求(删除列和重命名标题)。我将其保留是为了让您了解发生了什么。
基本上,我在日期 id 上使用 groupby 拆分您的数据框,并在最后将它们拼凑在一起。
另外,根据您的输入,我不认为您对 b_sent_new 的预期输出计算都是正确的。如果我在这里错了,请告诉我。
dflist = []
def calc_new(x):
# print(x[(x['b_id']==1) & (x['id'].str.contains('C_'))].sort_values(['timestamp', 'b_id'], ascending=[True, True]).reset_index(drop=True))
# print(x[(x['b_id']==2) & (x['id'].str.contains('V_'))].sort_values(['timestamp', 'b_id'], ascending=[True, True]).reset_index(drop=True))
# print(x[(x['b_id']==1) & (x['id'].str.contains('V_'))].sort_values(['timestamp', 'b_id'], ascending=[True, True]).reset_index(drop=True))
# print(x[(x['b_id']==2) & (x['id'].str.contains('C_'))].sort_values(['timestamp', 'b_id'], ascending=[True, True]).reset_index(drop=True))
a = x[(x['b_id']==1) & (x['id'].str.contains('C_'))].sort_values(['timestamp', 'b_id'], ascending=[True, True]).reset_index(drop=True)
b = x[(x['b_id']==2) & (x['id'].str.contains('V_'))].sort_values(['timestamp', 'b_id'], ascending=[True, True]).reset_index(drop=True)
c = x[(x['b_id']==1) & (x['id'].str.contains('V_'))].sort_values(['timestamp', 'b_id'], ascending=[True, True]).reset_index(drop=True)
d = x[(x['b_id']==2) & (x['id'].str.contains('C_'))].sort_values(['timestamp', 'b_id'], ascending=[True, True]).reset_index(drop=True)
e = a.merge(b, left_index=True, right_index=True)
e['b_sent_new'] = e['b_sent_x'] + e['b_sent_y']
# print(e)
f = d.merge(c, left_index=True, right_index=True)
f['b_sent_new'] = f['b_sent_x'] + f['b_sent_y']
# print(f)
dflist.append(e)
dflist.append(f)
return None
dft = df.groupby('timestamp').apply(calc_new)
# dflist
final_df = pd.concat(dflist)
final_df
timestamp_x t_id_x b_id_x id_x b_sent_x lc_x timestamp_y t_id_y b_id_y id_y b_sent_y lc_y b_sent_new
0 6/1/2020 9:00 25 1 C_0 25 540.0 6/1/2020 9:00 25 2 V_0 26 NaN 51
1 6/1/2020 9:00 25 1 C_1 25 540.0 6/1/2020 9:00 25 2 V_1 26 NaN 51
2 6/1/2020 9:00 25 1 C_2 25 540.0 6/1/2020 9:00 25 2 V_2 26 NaN 51
3 6/1/2020 9:00 25 1 C_3 28 478.0 6/1/2020 9:00 25 2 V_3 26 NaN 54
0 6/1/2020 9:00 25 2 C_0 26 510.0 6/1/2020 9:00 25 1 V_0 25 NaN 51
1 6/1/2020 9:00 25 2 C_1 26 510.0 6/1/2020 9:00 25 1 V_1 25 NaN 51
2 6/1/2020 9:00 25 2 C_2 27 510.0 6/1/2020 9:00 25 1 V_2 25 NaN 52
3 6/1/2020 9:00 25 2 C_3 32 300.0 6/1/2020 9:00 25 1 V_3 91 NaN 123
0 6/1/2020 9:30 25 1 C_0 10 140.0 6/1/2020 9:30 25 2 V_0 25 NaN 35
1 6/1/2020 9:30 25 1 C_1 20 340.0 6/1/2020 9:30 25 2 V_1 35 NaN 55
2 6/1/2020 9:30 25 1 C_2 25 240.0 6/1/2020 9:30 25 2 V_2 45 NaN 70
3 6/1/2020 9:30 25 1 C_3 30 578.0 6/1/2020 9:30 25 2 V_3 25 NaN 55
0 6/1/2020 9:30 25 2 C_0 15 140.0 6/1/2020 9:30 25 1 V_0 25 NaN 40
1 6/1/2020 9:30 25 2 C_1 20 340.0 6/1/2020 9:30 25 1 V_1 25 NaN 45
2 6/1/2020 9:30 25 2 C_2 35 240.0 6/1/2020 9:30 25 1 V_2 25 NaN 60
3 6/1/2020 9:30 25 2 C_3 40 578.0 6/1/2020 9:30 25 1 V_3 91 NaN 131
【讨论】:
谢谢! @Jonathan Leon 获取此代码!它对我来说非常完美。虽然它需要一点时间,但由于我庞大的数据集的大小,它可以忽略不计。 谢谢!很高兴它奏效了。我无法理解矢量化它,所以 apply() 就是这样。以上是关于如何在熊猫数据框的行之间应用多个条件创建目标数据框的主要内容,如果未能解决你的问题,请参考以下文章