00_*_*_00 7 python merge pandas
我有两个数据帧
df_a=
Start Stop Value
0 0 100 0.0
1 101 200 1.0
2 201 1000 0.0
df_b=
Start Stop Value
0 0 50 0.0
1 51 300 1.0
2 301 1000 0.0
Run Code Online (Sandbox Code Playgroud)
我想生成一个DataFrame包含由Startand 标识的区间Stop,其中Value df_a与df_b 相同.对于每一个间隔,我想存储:如果Value是相同的,并且这是在值df_a和df_b.期望的输出:
df_out=
Start Stop SameValue Value_dfA Value_dfB
0 50 1 0 0
51 100 0 0 1
101 200 1 1 1
201 300 0 0 1
[...]
Run Code Online (Sandbox Code Playgroud)
不确定这是否是最好的方法,但您可以reindex, join, groupby和agg来获取间隔,例如:
展开每个值,使索引成为范围 (到)df中的每个值,并使用这些值:StartStopreindex()pad
In []:\ndf_a_expanded = df_a.set_index('Start').reindex(range(max(df_a['Stop'])+1)).fillna(method='pad')\ndf_a_expanded\n\nOut[]:\n Stop Value\nStart \n0 100.0 0.0\n1 100.0 0.0\n2 100.0 0.0\n3 100.0 0.0\n4 100.0 0.0\n...\n997 1000.0 0.0\n998 1000.0 0.0\n999 1000.0 0.0\n1000 1000.0 0.0\n\n[1001 rows x 2 columns]\n\nIn []:\ndf_b_expanded = df_b.set_index('Start').reindex(range(max(df_b['Stop'])+1)).fillna(method='pad')\nRun Code Online (Sandbox Code Playgroud)\n\n将两个扩展连接起来dfs:
In []:\ndf = df_a_expanded.join(df_b_expanded, lsuffix='_dfA', rsuffix='_dfB').reset_index()\ndf\n\nOut[]:\n Start Stop_dfA Value_dfA Stop_dfB Value_dfB\n0 0 100.0 0.0 50.0 0.0\n1 1 100.0 0.0 50.0 0.0\n2 2 100.0 0.0 50.0 0.0\n3 3 100.0 0.0 50.0 0.0\n4 4 100.0 0.0 50.0 0.0\n...\nRun Code Online (Sandbox Code Playgroud)\n\n注意:您可以忽略这些Stop列,也可以在上一步中删除它们。
没有标准方法groupby只能处理连续值 (\xc3\xa0 la itertools.groupby),因此求助于cumsum()hack:
In []:\ngroups = (df[['Value_dfA', 'Value_dfB']] != df[['Value_dfA', 'Value_dfB']].shift()).any(axis=1).cumsum()\ng = df.groupby([groups, 'Value_dfA', 'Value_dfB'], as_index=False)\nRun Code Online (Sandbox Code Playgroud)\n\n现在您可以通过使用,聚合组来获得您想要的结果min:max
In []:\ndf_out = g['Start'].agg({'Start': 'min', 'Stop': 'max'})\ndf_out\n\nOut[]:\n Value_dfA Value_dfB Start Stop\n0 0.0 0.0 0 50\n1 0.0 1.0 51 100\n2 1.0 1.0 101 200\n3 0.0 1.0 201 300\n4 0.0 0.0 301 1000\nRun Code Online (Sandbox Code Playgroud)\n\n现在您只需添加SameValue列,如果需要,可以对列进行排序以获得您想要的确切输出:
In []:\ndf_out['SameValue'] = (df_out['Value_dfA'] == df_out['Value_dfB'])*1\ndf_out[['Start', 'Stop', 'SameValue', 'Value_dfA', 'Value_dfB']]\n\nOut[]:\n Start Stop SameValue Value_dfA Value_dfB\n0 0 50 1 0.0 0.0\n1 51 100 0 0.0 1.0\n2 101 200 1 1.0 1.0\n3 201 300 0 0.0 1.0\n4 301 1000 1 0.0 0.0\nRun Code Online (Sandbox Code Playgroud)\n\n这假设两个数据帧的范围相同,或者您将需要处理NaN通过join().
| 归档时间: |
|
| 查看次数: |
296 次 |
| 最近记录: |