根据相邻列值 Pandas 从列中按第一个或第二个空格提取字符串

Posted

技术标签:

【中文标题】根据相邻列值 Pandas 从列中按第一个或第二个空格提取字符串【英文标题】:extract string by first or second space from column depending on adjacent columns value Pandas 【发布时间】:2020-01-28 15:43:27 【问题描述】:

我有一个包含产品代码和产品类型的数据框。

material_description            component_type_or_status
SF 1243545gbe ff ee rr oo       SF
LF 2324344ire ff ee rr oo       LF
BF 3434333fre ff gg hh 23       BF
IA SF 3434333fre ff gg 22 re    IA
ZZ LF 34391r33b ff tn 33        ZZ

我想创建一个名为材料代码的新列,它根据产品类型的值从产品代码列左侧提取第二个字符串或第三个字符串

如果 SFBFLF 在左侧第一个空格之后返回字符串

如果 IAZZ 在左数第二个空格后返回字符串

这是我的功能。它陷入了一个循环,我不确定我的逻辑是否正确。 使用 Pandas 执行此操作的最佳方法是什么?

def parse_material_description(x):
    df = infile.parse(sheet_name='Unit of Measure')
    df['component_type_or_status'] = df['Material Description'].str[:2]

    try:
        if x['component_type_or_status'] == 'SF':
            df['material_code'] = df['Material Description'].str.split(" ",1)

        elif x['component_type_or_status'] == 'LF':
            df['material_code'] = df['Material Description'].str.split(" ",1)

        elif x['component_type_or_status'] == 'BF':
            df['material_code'] = df['Material Description'].str.split(" ",1)

        elif x['component_type_or_status'] == 'IA':
            df['material_code'] = df['Material Description'].str.split(" ",2)            

        elif x['component_type_or_status'] == 'ZZ':
            df['material_code'] = df['Material Description'].str.split(" ",2)            

        elif x['component_type_or_status'] == None:
            return ''
    except: IndexError

df['component_type_or_status'] = df.apply(parse_material_description, axis=1) 

【问题讨论】:

【参考方案1】:

我认为在一行中使用np.where 可能会更容易一些:

import pandas as pd
import numpy as np
data = 'material':['SF 1243545gbe ff ee rr oo','LF 2324344ire ff ee rr oo','ZZ LF 34391r33b ff tn 33'],'type':['SF','LF','ZZ']
df = pd.DataFrame(data)
df['material_code'] = np.where(df['type'].isin(['SF','LF','BF']),df['material'].str.split(" ").str.get(1),df['material'].str.split(" ").str.get(2))
print(df)

输出:

                    material type material_code
0  SF 1243545gbe ff ee rr oo   SF    1243545gbe
1  LF 2324344ire ff ee rr oo   LF    2324344ire
2   ZZ LF 34391r33b ff tn 33   ZZ     34391r33b

【讨论】:

【参考方案2】:

如果您的材料代码具有代表性,您可以改为这样做;

df['material_code'] = df['material_description'].str.extract(r'\s+([a-z0-9]+)\s+')

【讨论】:

【参考方案3】:

这是一种方法:

代码:

df['material code']=''
for i in range(0,len(df['component_type_or_status'])):
    if (df['component_type_or_status'][i] == 'SF') or (df['component_type_or_status'][i] == 'LF') or (df['component_type_or_status'][i] == 'BF'):
        df['material code'][i]=' '.join(df['material_description'][i].split()[1:2])
    else:
        df['material code'][i]=' '.join(df['material_description'][i].split()[2:3])

输出:

    material_description            component_type_or_status    material code
0   SF 1243545gbe ff ee rr oo       SF                          1243545gbe
1   LF 2324344ire ff ee rr oo       LF                          2324344ire
2   BF 3434333fre ff gg hh 23       BF                          3434333fre
3   IA SF 3434333fre ff gg 22 re    IA                          3434333fre
4   ZZ LF 34391r33b ff tn 33        ZZ                          34391r33b

df 这里是您的初始数据框。

【讨论】:

没有必要使用for和if,你可以使用其他效率更高的函数。另外,我认为 op 希望只获得列表中的 1/2 位置,而不是从该位置开始。 @CeliusStingher 你说得对,np.where 应该是显而易见的选择。为什么我没有想到呢? :)

以上是关于根据相邻列值 Pandas 从列中按第一个或第二个空格提取字符串的主要内容,如果未能解决你的问题,请参考以下文章

遍历 pandas 行并根据其他列中的值设置列值

PANDAS 从列中找到确切的给定字符串/单词

在python pandas中groupby之后从列中填充缺失的行

pandas 按正则表达式条件从列中过滤字符串并替换它

需要使用 pandas.str() 使用字符串列表从列中选择值 [重复]

在NodeJS中按值排序数组