繁体   English   中英

pandas df 中的单独字符串编号范围

[英]seperate string number ranges in pandas df

我有一个看起来像这样的 df

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

所需的 output 应如下所示

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

因此,总计列 pres.net 每种类型的多个值。 范围值用两个number分隔,两个数字被两个..和一个值(没有范围)呈现在两个| |之间。 | |

假设您的范围是包容性的,我假设这是因为您的“3..4”转换为一行 3 和一行 4,并假设您忘记将 Mike 14 和 Mike 15 放入您的示例 output,我发现以下解决方案:

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'})

我们写一个 function 来解析字符串,也就是用|分割字符串如果字符串已经是数字,则将数字转换为整数。 否则,它是一个范围,所以我们再次用..分割并创建一个包含范围内所有数字的列表。 最后,我们返回一个包含字符串中所有数字的 pd.Series。

然后,我们将 function 应用于带有df['range'].apply的列并堆叠结果。 为了确保我们仍然保留名称,我们必须首先将其设置为 dataframe 的索引。

你可以做

# 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM