【问题标题】:Check values between two columns检查两列之间的值
【发布时间】:2021-11-20 00:26:42
【问题描述】:

我需要在我的 df 的两列 -A 和 B- 上执行以下步骤,并将结果输出到 C:

1) check if value from B is present in A -on row, at any position
2) if present but in another format then remove
3) add value from B in A and output in C



A                          B                C
tshirt for women           TSHIRT           TSHIRT for women 
Zaino Estensibile          SJ Gang          SJ Gang Zaino Estensibile 
Air Optix plus             AIR OPTIX        AIR OPTIX plus

在 A 和 B 之间连接并删除重复项的解决方法:

版本 1

def uniqueList(row):
    words = str(row).split(" ")
    unique = words[0]
    for w in words:
        if w.lower() not in unique.lower() :
            if w.lower()not in my_list:
                unique = unique + " " + w

    return unique
    
df["C"] = df["C"].apply(uniqueList)

版本2

sentences = df["B"] .to_list()
for s in sentences:
    s_split = s.split(' ')  # keep original sentence split by ' '
    s_split_without_comma = [i.strip(',') for i in s_split]
    # method 1: re
    compare_words = re.split(' |-', s)
    # method 2: itertools
    compare_words = list(itertools.chain.from_iterable([i.split('-') for i in s_split]))
    method 3: DIY
    compare_words = []
    for i in s_split:
        compare_words += i.split('-')

    # strip ','
    compare_words_without_comma = [i.strip(',') for i in compare_words]

    start to compare
    need_removed_index = []
    for word in compare_words_without_comma:
        matched_indexes = []
        for idx, w in enumerate(s_split_without_comma):
            if word.lower() in w.lower().split('-'):
                matched_indexes.append(idx)
        if len(matched_indexes) > 1:  # has_duplicates
            need_removed_index += matched_indexes[1:]
    need_removed_index = list(set(need_removed_index))

    # keep remain and join with ' '
    print(" ".join([i for idx, i in enumerate(s_split) if idx not in need_removed_index]))
    # print(sentences)

print(sentences)

这些都不能正常工作,因为这不是最好的方法。

【问题讨论】:

  • 您的问题是什么?您如何编辑问题并添加您尝试过的所有内容以及您在这里遇到的问题。
  • 这似乎是一道家庭作业题,你自己的努力在哪里?
  • @Umar.HI 实际上已经尝试了一种解决方法,连接和删除重复的有效但在某些情况下不需要删除所有重复的单词,整数和其他特定单词也是如此。
  • 你能把代码也贴出来吗?
  • @Umar.H 当然,完成。还有第三个尝试,但我无法在问题中发布更多代码

标签: python pandas duplicates concatenation


【解决方案1】:

使用集合,获取A 中的字符串而不是B 中的字符串。将这些字符串作为一个集合放在C 列中

  df['C'] = [(set(a).difference(b)) for a, b in zip(df['A'].str.upper().str.split('\s'), df['B'].str.upper().str.split('\s'))]

如果 B 是 A 的子字符串,则删除新列 C 的括号和逗号以及 concatenate 与列 B。如果不是,只需连接 B 和 A。

代码如下;

df['C']= np.where([a in b for a, b in zip(df.B.str.lower(),df.A.str.lower())], df['B'] + ' ' + df['C'].str.join(',').str.replace(',',' ').str.lower(), df['B'] + ' ' + df['A'])

打印(df)

输出

               A          B                          C
0   tshirt for women     TSHIRT           TSHIRT for women
1  Zaino Estensibile    SJ Gang  SJ Gang Zaino Estensibile
2     Air Optix plus  AIR OPTIX             AIR OPTIX plus

【讨论】:

  • 谢谢,但我无法转换为更低并删除所有逗号。我很抱歉,我应该提到的,一切都应该保持不变,包括发生
  • 查看输出。它确实有效。转换为较低的等只是一种转换方法,不会影响原始数据帧。这是达到目的的手段
【解决方案2】:

这是一个使用正则表达式的解决方案,假设 df 是数据框的名称。

所以思路很简单,如果 B 在 A 中有东西,就用 B 的值替换它。否则返回字符串 B + A。

import re

def create_c(row):
    if re.sub(row['B'], row['B'], row['A'], flags=re.IGNORECASE) == row['A']:
        return row['B'] + ' ' + row['A']
    return re.sub(row['B'], row['B'], row['A'], flags=re.IGNORECASE)


df['C'] = df.apply(create_c, axis=1)

编辑#1:我忘了在 re.sub() 语句之前添加 return 关键字。

下面是在shell中运行代码:

>>> import pandas as pd
>>> data = [['tshirt for women', 'TSHIRT'], ['Zaino Estensibile', 'SJ Gang']]
>>> df = pd.DataFrame(data, columns=['A', 'B'])
>>> df
                   A        B
0   tshirt for women   TSHIRT
1  Zaino Estensibile  SJ Gang
>>> 
>>>
>>> import re
>>> def create_c(row):
...     if re.sub(row['B'], row['B'], row['A'], flags=re.IGNORECASE) == row['A']:
...         return row['B'] + ' ' + row['A']
...     return re.sub(row['B'], row['B'], row['A'], flags=re.IGNORECASE)
... 
>>> 
>>> df['C'] = df.apply(create_c, axis=1)
>>> df
                   A        B                          C
0   tshirt for women   TSHIRT           TSHIRT for women
1  Zaino Estensibile  SJ Gang  SJ Gang Zaino Estensibile
>>> 

【讨论】:

  • 谢谢,但没有将 C 列中的值带入
  • 它还为较低/较高的情况创建重复项
  • @Isa,我已经编辑了答案,我忘了写return关键字。
  • 非常感谢,这是我拥有的最好的版本,除了一个例外,它会在 A 列的值这样的情况下创建重复项:L'OCCITANE - OLIO DOCCIA,B 中的 balue:L'Occitane,结果C: L'Occitane L'OCCITANE - OLIO DOCCIA。我可以添加什么来避免这种情况吗?再次感谢您的所有努力
  • @Isa 这是因为´ 字符在L´OccitaneL'OCCITANE 中不同。应该怎么办?
猜你喜欢
  • 2021-12-02
  • 1970-01-01
  • 2017-05-21
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多