将数字范围转换为连续范围

2024-04-25 04:19:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个大约9000的数据集,区域范围的格式是[1-5,10-99100-115],我想在提供的数据集中展开数据和行的格式。你知道吗

我的第一个想法可能是在“特丽”系列中循环播放pd系列(范围(i,100)),但这不会产生下面的输出。你知道吗

感谢您的帮助。你知道吗

import pandas as pd
d={'Peril':['Fire','Wind'],'Terri':[1-5,6-10],'Premium':[100,200]}
output={'Peril':['Fire','Fire','Fire','Fire','Fire','Wind','Wind','Wind','Wind','Wind'],'Terri':[1,2,3,4,5,6,7,8,9,10],'Premium':[100,100,100,100,100,200,200,200,200,200]}
df=pd.DataFrame(data=d)
expected_output=pd.DataFrame(data=output)

Tags: 数据import区域dataframepandasoutputdataas
3条回答

唯一可行的方法是,如果启动DataFrame的Terri列是字符串:

d={'Peril':['Fire','Wind'],'Terri':['1-5','6-10'],'Premium':[100,200]}
df = pd.DataFrame(d)
print(df)
#  Peril Terri  Premium
#0  Fire   1-5      100
#1  Wind  6-10      200

如果拆分-上的Terri列中的字符串,则可以将其用作range的输入,除非需要在stop值中添加一个以包含端点。为了方便起见,您可以定义自己的范围函数:

def myRange(a, b):
    return range(a, b+1)

现在可以拆分列,应用myRange函数,并堆叠结果:

temp = pd.DataFrame(
    df['Terri'].str.split("-")\
        .apply(lambda x: pd.Series(myRange(*map(int, x))))\
        .stack()\
        .reset_index(level=1, drop=True),
    columns=["Terri"]
)
print(temp)
#   Terri
#0      1
#0      2
#0      3
#0      4
#0      5
#1      6
#1      7
#1      8
#1      9
#1     10

最后将此结果与原始数据帧合并:

print(df.drop(["Terri"], axis=1).join(temp))
#  Peril  Premium  Terri
#0  Fire      100      1
#0  Fire      100      2
#0  Fire      100      3
#0  Fire      100      4
#0  Fire      100      5
#1  Wind      200      6
#1  Wind      200      7
#1  Wind      200      8
#1  Wind      200      9
#1  Wind      200     10

同样的事情,浓缩:

df.drop(["Terri"], axis=1).join(
    pd.DataFrame(
        df['Terri'].str.split("-")\
            .apply(lambda x: pd.Series(myRange(*map(int, x))))\
            .stack()\
            .reset_index(level=1, drop=True),
        columns=["Terri"]
    )
)

假设Terri要包含字符串范围,而不是减法运算,您可以创建范围的数据帧,然后stack利用公共索引上的join来扩展原始帧。你知道吗


u = df['Terri'].str.split('-', expand=True).astype(int).values

j = pd.DataFrame(
    [np.arange(start, stop+1) for start, stop in u]
)

j.stack().reset_index(1, drop=True).to_frame('Terri')

df.drop('Terri', 1).join(f)

  Peril  Premium  Terri
0  Fire      100      1
0  Fire      100      2
0  Fire      100      3
0  Fire      100      4
0  Fire      100      5
1  Wind      200      6
1  Wind      200      7
1  Wind      200      8
1  Wind      200      9
1  Wind      200     10

因为stack的行为将删除空值,所以您的范围不必是统一的长度。你知道吗

使用几个助手列表理解,然后使用^{}^{}^{}

import numpy as np
import pandas as pd

ranges = [np.arange(s, e+1) for s, e in [list(map(int, x)) for x in df.Terri.str.split('-')]]
lens = [len(x) for x in ranges]

df_new = df.loc[df.index.repeat(lens)].assign(Terri=np.hstack(ranges))

[输出]

  Peril  Terri  Premium
0  Fire      1      100
0  Fire      2      100
0  Fire      3      100
0  Fire      4      100
0  Fire      5      100
1  Wind      6      200
1  Wind      7      200
1  Wind      8      200
1  Wind      9      200
1  Wind     10      200

作为参考,ranges看起来像:

[array([1, 2, 3, 4, 5]), array([ 6,  7,  8,  9, 10])]

lens看起来像:

[5, 5]

相关问题 更多 >