【问题标题】:Replace values by order of list按列表顺序替换值
【发布时间】:2021-02-27 22:31:09
【问题描述】:
keywords = ['Small', 'Medium', 'Large']
df.column
0   The Small, Large, Medium
1   The fast Medium, Small XS
2   He was a Medium, Large or Small

如果一行包含关键字,我如何告诉 pandas:

  1. 替换关键字,使关键字按列表顺序显示
  2. 如果关键字包含后缀“XS”,请在步骤 1 中包含后缀

预期输出:

0 The Small, Medium, Large 
1 The fast Small XS, Medium
2 He was a Small, Medium or Large

【问题讨论】:

  • XS 是唯一有效的后缀吗?如果不是,你怎么知道第 2 行的or 不是Medium 的后缀?
  • 是的 XS 是唯一有效的后缀
  • 每个关键字是否可以重复,或者每个关键字只有一个,例如Medium, MediumSmall, Small XS 有效吗?
  • 在我的情况下不会重复,但我想如果可能的话,越通用的解决方案越好
  • 您有 Small XS 和 Small XS 之间的订单,还是想保留它们出现时的订单

标签: python python-3.x pandas


【解决方案1】:

一种方法是:

  1. 将字符串拆分为与关键字匹配的单词(带或不带XS 后缀),或使用re.findall 的其他不匹配部分
  2. 根据关键字列表中的索引对匹配的单词进行排序
  3. 使用排序后的关键字重建单词列表
  4. 将字符串重新连接在一起

你可以用这个函数做到这一点:

def sizesorter(s, keywords):
    words = re.findall(r'((?:\b(?:' + '|'.join(keywords) + r')\b)(?:\sXS)?|(?:[^\s]*(?:\s|$)))', s, re.I)
    sizes = iter(sorted([w for w in words if w.split(' ')[0] in keywords], key=lambda w:keywords.index(w.split(' ')[0])))
    words = [w if w.split(' ')[0] not in keywords else next(sizes) for w in words]
    return ''.join(words)

然后您可以将该函数应用于列。例如:

import pandas as pd
import re

df = pd.DataFrame({ 'column' : ['The Small, Large, Medium',
'The fast Medium, Small XS',
'He was a Medium, Large or Small',
'small, Large a metre'
] })

def sizesorter(s, keywords):
    words = re.findall(r'((?:\b(?:' + '|'.join(keywords) + r')\b)(?:\sXS)?|(?:[^\s]*(?:\s|$)))', s, re.I)
    sizes = iter(sorted([w for w in words if w.split(' ')[0] in keywords], key=lambda w:keywords.index(w.split(' ')[0])))
    words = [w if w.split(' ')[0] not in keywords else next(sizes) for w in words]
    return ''.join(words)
    
df.column = df.column.apply(sizesorter, args=(['Small', 'Medium', 'Large'], ))

print(df)

输出:

                            column
0         The Small, Medium, Large
1        The fast Small XS, Medium
2  He was a Small, Medium or Large

改编自this answer的单词列表的部分排序。

【讨论】:

  • @asd 很高兴这对你有用。这里已经很晚了 - 我会在这个问题上睡觉,但你可能会更快地得到一个新问题的回应,你可以参考这个问题的上下文。我突然想到将Size 添加到关键字列表中可能会起作用,但它不太正确ideone.com/wUGJFR
  • @asd 快速修复单词删除问题,我不允许字符串末尾的非大小单词,将模式更改为r'((?:' + '|'.join(keywords) + ')(?:\sXS)?|(?:[^\s]*(?:\s|$)))'。仍在考虑如何最好地解决Size 问题。有一些想法,但真正的工作正在路上......:P
  • @asd 没有太多时间来研究这个,但如果不是最有效的话,这里有一些可行的方法:ideone.com/fUy1a7
  • @asd 所有代码都区分大小写,这可能会导致该问题。您需要在比较之前转换大小写(也许让关键字全部小写并在比较之前翻译每个单词)
  • @asd 我认为这可以满足您的需求(并且不区分大小写)。有点丑,可惜没时间再看……ideone.com/fbvaIq
猜你喜欢
  • 2023-01-11
  • 2019-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多