python pandas两个 Dataframe 的复杂合并

eimct9ow  于 2023-04-04  发布在  Python
关注(0)|答案(2)|浏览(91)

我有一个区间(假设从0到45),我根据值的变化将其分割。问题是我有2个值(value 1和value 2),我试图根据它们分割图形,然后通过创建更多的点分割并给它们一个值来连接它们(参见示例)
我有两个pandas dataframes如下:
| 来自1|至1|数值1|
| --------------|--------------|--------------|
| 0|三|1.|
| 三|十五岁|2.|
| 十五岁|三十|1.|
| 三十|四十五|3.|
| From2|至2|数值2|
| --------------|--------------|--------------|
| 0|五|(B)|
| 五|十一|(a)|
| 十一|三十|(c)|
| 三十|四十五|(a)|
我想加入他们,得到这样的东西:
| 从|到|数值1|数值2|
| --------------|--------------|--------------|--------------|
| 0|三|1.|(B)|
| 三|五|2.|(B)|
| 五|十一|2.|(a)|
| 十一|十五岁|2.|(c)|
| 十五岁|三十|1.|(c)|
| 三十|四十五|3.|(a)|
我尝试从列中获取所有值:From 1和From 2并创建From列,但我不知道如何继续。

4xrmg8kj

4xrmg8kj1#

您可以为每个步骤创建单独的行(这里考虑1),然后使用双groupby.agg

def reindex_int(df):
    tmp = df.loc[df.index.repeat(df['To'].sub(df['From']))]
    s = tmp.groupby(level=0).cumcount()

    tmp['From'] += s
    tmp['To'] = tmp['From']+1
    
    return tmp

out = (pd.concat([reindex_int(df1.rename(columns={'From1': 'From', 'To1': 'To'})),
                  reindex_int(df2.rename(columns={'From2': 'From', 'To2': 'To'}))])
         .groupby(['From', 'To'], as_index=False).first()
         .pipe(lambda d: d.groupby(d[['Value1', 'Value2']]
                                   .ne(d[['Value1', 'Value2']].shift())
                                   .any(axis=1).cumsum())
                           .agg({'From': 'min', 'To': 'max',
                                 'Value1': 'first', 'Value2': 'first'})
              )
      
      )

输出:

From  To  Value1 Value2
1     0   3     1.0     b)
2     3   5     2.0     b)
3     5  11     2.0     a)
4    11  15     2.0     c)
5    15  30     1.0     c)
6    30  45     3.0     a)

中间体:

reindex_int(df1.rename(columns={'From1': 'From', 'To1': 'To'}))

   From  To  Value1
0     0   1       1
0     1   2       1
0     2   3       1
1     3   4       2
1     4   5       2
1     5   6       2
1     6   7       2
1     7   8       2
1     8   9       2
1     9  10       2
1    10  11       2
1    11  12       2
1    12  13       2
1    13  14       2
1    14  15       2
2    15  16       1
2    16  17       1
2    17  18       1
2    18  19       1
2    19  20       1
2    20  21       1
2    21  22       1
2    22  23       1
2    23  24       1
2    24  25       1
2    25  26       1
2    26  27       1
2    27  28       1
2    28  29       1
2    29  30       1
3    30  31       3
3    31  32       3
3    32  33       3
3    33  34       3
3    34  35       3
3    35  36       3
3    36  37       3
3    37  38       3
3    38  39       3
3    39  40       3
3    40  41       3
3    41  42       3
3    42  43       3
3    43  44       3
3    44  45       3
wfveoks0

wfveoks02#

下面是一个替代方法:

ndf = (pd.merge(df.assign(t = [range(s,e+1) for s,e in zip(df['From1'],df['To1'])]).explode('t'),
df2.assign(t = [range(s,e+1) for s,e in zip(df2['From2'],df2['To2'])])
.explode('t')))

ndf = (ndf.groupby(['Value1','Value2'],sort=False)
.agg(From = ('t','first'),To = ('t','last'))
.drop_duplicates(keep=False)
.reset_index()))

输出:

Value1 Value2 From  To
0     1.0     b)    0   3
1     2.0     b)    3   5
2     2.0     a)    5  11
3     2.0     c)   11  15
4     1.0     c)   15  30
5     3.0     a)   30  45

相关问题