通过匹配多个列和条件对数据框进行排序

问题描述 投票:0回答:1

输入数据:

| source_element |   source_text     | source_entity  | target_element | target_text  | target_entity  |
|---------------|-------------------|----------------|---------------|-------------|----------------|
|    vvvvvv      |       ['body']    |      name      |     aaaaa      |     ceo      |      code      |
|    vvvvvv      |       ['body']    |      name      |     bbbbb      |     cap      |      code      |
|    vvvvvv      |  ['body', 'fat']  |      name      |     ccccc      |     fat      |      name      |
|    hhhhhh      | ['man', 'hat']    |      name      |     kkkkk      |     hat      |      name      |
|    kkkkk       |      ['hat']      |      name      |     lllll      |     700      |     price      |
|    kkkkk       |      ['hat']      |      name      |     fffff      |     mud      |      code      |
|    eeeee       |     ['strong']    |      name      |     zzzzz      |     300      |     price      |
|    ssssss      |      ['head']     |      name      |     ddddd      |     zip      |      code      |
|    ssssss      | ['head', 'strong']|      name      |     eeeee      |    strong    |      name      |
|    ssssss      |  ['head', 'part'] |      name      |     uuuuu      |     part     |      name      |
|    uuuuu       |      ['part']     |      name      |     xxxxx      |     190      |     price      |

输出:

|  source_text   |  source_entity    |  target_text   |  target_entity    |
|-----------------|----------------|----------------|-------------------|
| ['body', 'fat']|       name        |     'ceo'      |       code        |
| ['body', 'fat']|       name        |     'cap'      |       code        |
| ['man', 'hat'] |       name        |     '700'      |      price        |
| ['man', 'hat'] |       name        |     'mud'      |       code        |
| ['head', 'strong'] |    name        |     'zip'      |       code        |
| ['head', 'strong'] |    name        |     '300'      |      price        |
| ['head', 'part'] |      name        |     'zip'      |       code        |
| ['head', 'part'] |      name        |     '190'      |      price        |

我需要满足这些条件的输出:

1.如果 source_entity 和 target_entity 是“名称”,则该特定行的 source_element 或 target_element 与整个数据帧中任何行的 source_element 匹配,将 target_text 和 text_entity 替换为数据帧的匹配行,并删除具有 source_entity 和 target_entity 的行是“名字”。

2.保留不受上述条件影响的其他数据帧行

pandas dataframe match multiple-columns
1个回答
1
投票
import pandas as pd

cond = (df['source_entity'] == 'name') & (df['target_entity'] == 'name')
bbb = df[~df.index.isin(df[cond].index)]

def fff(x):
    a = bbb[bbb['source_element'] == df.loc[x, 'source_element']]
    b = bbb[bbb['source_element'] == df.loc[x, 'target_element']]
    if len(a) > 0:
        df.loc[a.index, 'source_text'] = df.loc[x, 'source_text']
        return x
    elif len(b) > 0:
        df.loc[b.index, 'source_text'] = df.loc[x, 'source_text']
        return x


aaa = [fff(i) for i in df[cond].index]
ind = df.index.isin(aaa)

print(df[~ind][['source_text', 'source_entity', 'target_text', 'target_entity']])

输出

     source_text source_entity target_text target_entity
0    'body  fat'          name       'ceo'          code
1    'body  fat'          name       'cap'          code
4      'man hat'          name       '700'         price
5  'head strong'          name       'zip'          code

如果您需要重置索引:

print(df[~ind][['source_text', 'source_entity', 'target_text', 'target_entity']].reset_index(drop=True))

更新

关于连续列表。 here 描述了这个问题。您可以使用 _set_value,但这只适用于一行。而在a.index和b.index中,恰好有好几行被选中

相反,您可以在 Series.str.join 的开头将所有列表转换为字符串:

df['source_text'] = df['source_text'].str.join(',')

如果您在选择后需要列表,请将所有内容返回到它的位置Series.str.split

df['source_text'] = df['source_text'].str.rsplit(',')
© www.soinside.com 2019 - 2024. All rights reserved.