【问题标题】:Appending column from one dataframe to another dataframe with multiple matches in loop将列从一个数据帧附加到另一个数据帧,循环中有多个匹配项
【发布时间】:2021-10-14 00:41:17
【问题描述】:

我的问题是这个问题的延伸:

Check if value in a dataframe is between two values in another dataframe

df1

    df1_Col     df1_start
0   A1          1200        
1   B2          4000        
2   B2          2500       

df2

    df2_Col     df2_start   df2_end       data
0   A1          1000        2000          DATA_A1
1   A1          900         1500          DATA_A1_A1
**2   A1          2000        3000          DATA_A1_A1_A1**
2   B1          2000        3000          DATA_B1
3   B2          2000        3000          DATA_B2

输出:

    df1_Col     df1_start     data
0   A1          1200          DATA_A1;DATA_A1_A1
1   B2          4000          
2   B2          2500          DATA_B2

我将df1_Col 的值与df2_Coldf1_start 进行比较,使其在df2_startdf2_end 的范围内,然后在df1 中添加data 列的值。如果有多个匹配项,则 data 可以与任何分隔符组合,例如 ';'。

代码如下:

for v,ch in zip(df1.df1_start, df1.df1_Col):
        df3 = df2[(df2['df2_start'] < v) & (df2['df2_end'] > v) & (df2['df2_Col'] ==ch)]
        data = df3['data']
        df1['data'] = data

使用循环是因为文件很大。

编辑:

期待您的帮助。

【问题讨论】:

  • 为什么在预期输出中得到 4000,它不在 df2_start 和 df2_end 之间?
  • 因为它是 df1 的一部分,并将列 data 附加到 df1。它可以是空白或破折号,表示该行没有任何匹配项。
  • 我认为这应该是1200,而不是df1_start中的1000
  • @AnuragDabas:已编辑,谢谢。

标签: python pandas dataframe append


【解决方案1】:

IIUC:

尝试通过merge()+groupby()+agg():

在df1上左合并然后检查'df1_start'是否在'df2_start'和'df2_end'之间并创建列'data'并将其值设置为None。然后我们在['df1_Col','df1_start']上分组并加入'的值日期'由';' 分隔,删除无:

out=df1.merge(df2,left_on='df1_Col',right_on='df2_Col',how='left',sort=True)
out.loc[~out['df1_start'].between(out['df2_start'], out['df2_end']), 'data'] = None
out=out.groupby(['df1_Col','df1_start'],as_index=False,sort=False)['data'].agg(lambda x:';'.join(x.dropna()))

out的输出:

   df1_Col  df1_start       data
0   A1          1200        DATA_A1;DATA_A1_A1
1   B2          4000    
2   B2          2500        DATA_B2

【讨论】:

  • 很好的答案,谢谢。但是我目前第一个脚本面临的唯一问题是它也在数据中添加了星号行(在问题中编辑),尽管它不符合介于df2_startdf2_end 之间的标准。第二个脚本添加“;”对于匹配为“False”的行。例如,考虑到我有超过 60,000 行,数据表看起来像这样“DATA_A1;;;;;;;;DATA_A1_A1”,数据列有点模棱两可。
  • 我试过修改后的代码:out=out.groupby(['chr','start','end'],as_index=False,sort=False)['data'].agg(lambda x: ';'.join(x.dropna())),但没有成功。
  • @aso 所以这两个脚本对你来说都很好,只是数据列看起来像这样"DATA_A1;;;;;;;;DATA_A1_A1"?
  • 第一个脚本给出了一个误报 data 在问题 DATA_A1;DATA_A1_A1;DATA_A1_A1_A1 中用星号提到的值,尽管第三个条目与 df2_startdf2_end 之间的条件不匹配(添加问题中的图片供您理解)。第二个脚本给了我模棱两可的data 列。
  • 完美运行...非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2021-04-03
  • 2021-05-12
  • 2023-03-25
  • 2020-08-20
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多