[英]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.