社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在python中,如何根据整数在ID中的位置拆分字符串类型的ID?

d.p • 4 年前 • 1985 次点击  

My pandas dataframe当前有一个名为BinLocation的列,其中包含仓库中物料的位置。例如: 如果零件位于A02列第33行,然后位于B21层,则BinLocation ID为A02033B21。 对于某些列,格式可能是A0233B21。命名约定不一致,但这不取决于我,现在我必须清理数据。 我想拆分字符串,这样对于BinLocation的任何给定输入,我都可以返回列、行和级别。最后,我想为dataframe创建3个新列(列、行、级别)。 如果不清楚,ID的一般结构是 ColumnChar_ColumnInt_RowInt_ColumnChar_LevelInt

现在,对于某些位置,ID由连字符分隔,因此我为这些位置编写了以下代码:

def forHyphenRow(s):
    return s.split('-')[1]
def forHyphenColumn(s):
    return s.split('-')[0]

def forHyphenLevel(s):
    return s.split('-')[2]

除了其他ID,我该怎么做? 此外,在数据框中是否有将数据框中的列分组在一起的方法?(所以A02都分组在一起,CB-22都分组在一起,等等)

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/131264
文章 [ 2 ]  |  最新文章 4 年前
S Rawson
Reply   •   1 楼
S Rawson    4 年前

如果字符串的前三个字符始终作为列,后三个字符作为级别(因此行作为中间的所有字符):

def forNotHyphenColumn(s):
    return s[:3]


def forNotHyphenLevel(s):
    return s[-3:]


def forNotHyphenRow(s):
    return s[3:-3]

然后,您可以通过为BinLocation项创建单独的DataFrame列并使用 df.sort_values() :

df = pd.DataFrame(data={"BinLocation": ["A02033B21", "C02044C12", "A0233B21"]})
# Create dataframe columns for BinLocation items
df["Column"] = df["BinLocation"].apply(lambda x: forNotHyphenColumn(x))
df["Row"] = df["BinLocation"].apply(lambda x: forNotHyphenRow(x))
df["Level"] = df["BinLocation"].apply(lambda x: forNotHyphenLevel(x))
# Sort values
df.sort_values(by=["Column"], ascending=True, inplace=True)

df
#Out: 
#  BinLocation Column  Row Level
#0   A02033B21    A02  033   B21
#2    A0233B21    A02   33   B21
#1   C02044C12    C02  044   C12

编辑:

也可以在中使用连字符函数 apply() :

df = pd.DataFrame(data={"BinLocation": ["A02033B21", "C02044C12", "A0233B21", "A01-33-C13"]})
# Create dataframe columns for BinLocation items
df["Column"] = df["BinLocation"].apply(lambda x: forHyphenColumn(x) if "-" in x else forNotHyphenColumn(x))
df["Row"] = df["BinLocation"].apply(lambda x: forHyphenRow(x) if "-" in x else forNotHyphenRow(x))
df["Level"] = df["BinLocation"].apply(lambda x: forHyphenLevel(x) if "-" in x else forNotHyphenLevel(x))
# Sort values
df.sort_values(by=["Column"], ascending=True, inplace=True)

df
#Out: 
#  BinLocation Column  Row Level
#3  A01-33-C13    A01   33   C13
#0   A02033B21    A02  033   B21
#2    A0233B21    A02   33   B21
#1   C02044C12    C02  044   C12
constantstranger
Reply   •   2 楼
constantstranger    4 年前

以下是一个答案:

  • 使用Python正则表达式语法解析ID(处理带有或不带连字符的情况,如果需要,可以调整以适应历史ID的其他特性)
  • 将ID设置为正规格式
  • 为ID组件添加列
  • 基于ID组件进行排序,以便将行“分组”在一起(尽管不是熊猫的“groupby”意思)
import pandas as pd
df = pd.DataFrame({'BinLocation':['A0233B21', 'A02033B21', 'A02-033-B21', 'A02-33-B21', 'A02-33-B15', 'A02-30-B21', 'A01-33-B21']})
print(df)
print()
df['RawBinLocation'] = df['BinLocation']
import re
def parse(s):
    m = re.match('^([A-Z])([0-9]{2})-?([0-9]+)-?([A-Z])([0-9]{2})$', s)
    if not m:
        return None
    tup = m.groups()
    colChar, colInt, rowInt, levelChar, levelInt = tup[0], int(tup[1]), int(tup[2]), tup[3], int(tup[4])
    tup = (colChar, colInt, rowInt, levelChar, levelInt)
    return pd.Series(tup)
df[['ColChar', 'ColInt', 'RowInt', 'LevChar', 'LevInt']] = df['BinLocation'].apply(parse)
df['BinLocation'] = df.apply(lambda x: f"{x.ColChar}{x.ColInt:02}-{x.RowInt:03}-{x.LevChar}{x.LevInt:02}", axis=1)
df.sort_values(by=['ColChar', 'ColInt', 'RowInt', 'LevChar', 'LevInt'], inplace=True, ignore_index=True)
print(df)

输出:

   BinLocation
0     A0233B21
1    A02033B21
2  A02-033-B21
3   A02-33-B21
4   A02-33-B15
5   A02-30-B21
6   A01-33-B21

   BinLocation RawBinLocation ColChar  ColInt  RowInt LevChar  LevInt
0  A01-033-B21     A01-33-B21       A       1      33       B      21
1  A02-030-B21     A02-30-B21       A       2      30       B      21
2  A02-033-B15     A02-33-B15       A       2      33       B      15
3  A02-033-B21       A0233B21       A       2      33       B      21
4  A02-033-B21      A02033B21       A       2      33       B      21
5  A02-033-B21    A02-033-B21       A       2      33       B      21
6  A02-033-B21     A02-33-B21       A       2      33       B      21