在Pandasdf中分隔字符串数字范围

sc4hvdpw  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(160)

我有一个df,它看起来像这样

Type    range
Mike    10..13|7|8|
Ni      3..4
NANA    2|1|6

所需的输出应如下所示

Type    range
Mike    10
Mike    11
Mike    12
Mike    13
Mike    7
Mike    8
Nico    3
Nico    4
NANA    2
NANA    1
NANA    6

因此,“合计”列显示每个类型的多个值。范围值显示为两个number,两个..将其分隔,一个值(无范围)显示在两个| |之间

sdnqo3pr

sdnqo3pr1#

假设您的范围是包含的(我之所以这样假设是因为您的'3..4'转换为包含3的行和包含4的行),并且假设您忘记在示例输出中输入Mike 14和Mike 15,我找到了以下解决方案:

import pandas as pd

def parse_str(s):
    numbers = []
    for v in s.rstrip('|').split('|'):
        if v.isdigit():
            numbers.append(int(v))
        else:
            start, end = v.split('..')
            numbers.extend(list(range(int(start), int(end)+1)))
    return pd.Series(numbers)

df.index = df['Type']
dfnew = df['range'].apply(parse_str).stack().reset_index(level=0).rename(columns={0: 'range'})

我们编写一个函数来解析字符串,这意味着用|拆分字符串,如果字符串已经是一个数字,则将数字转换为整数。否则,它是一个范围,所以我们再次用..拆分字符串,并创建一个包含范围内所有数字的列表。最后,我们返回一个包含字符串中所有数字的pd.Series。
然后,我们将该函数应用于df['range'].apply列,并将结果堆栈起来。为了确保仍然保留名称,我们必须首先将其设置为 Dataframe 的索引。

aurhwmvo

aurhwmvo2#

你可以做

# split by '|' and explode
df = df.assign(range=df['range'].str.split('|')).explode('range')

# get the range(i, j) if the string has '..'
df['range'] = df['range'].apply(lambda r: range(int(r.split('..')[0]), int(r.split('..')[1])) if (len(r.split('..')) == 2) else r)

# explode
df = df.explode('range')
df

    Type    range
0   Mike       10
0   Mike       11
0   Mike       12
0   Mike       13
0   Mike       14
0   Mike        7
0   Mike        8
1     Ni        3
2   NANA        2
2   NANA        1
2   NANA        6

相关问题