首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将数值范围转换为连续范围

将数值范围转换为连续范围
EN

Stack Overflow用户
提问于 2019-04-19 23:51:04
回答 4查看 150关注 0票数 1

我有一个大约9000的数据集,地区范围为1-5,10-99,100-115。我希望将数据和行扩展为所提供的数据集中的形式。

我的第一个想法可能是遍历序列'Terri‘并通过pd.series(range(i,100))运行它,但这不会产生下面的输出。

感谢你的帮助。

代码语言:javascript
运行
复制
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)
EN

回答 4

Stack Overflow用户

发布于 2019-04-20 00:35:13

使用几个助手列表理解,然后使用pandas.index.repeatDataFrame.assignnumpy.hstack

代码语言:javascript
运行
复制
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))

输出

代码语言:javascript
运行
复制
  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如下所示:

代码语言:javascript
运行
复制
[array([1, 2, 3, 4, 5]), array([ 6,  7,  8,  9, 10])]

lens看起来像这样:

代码语言:javascript
运行
复制
[5, 5]
票数 4
EN

Stack Overflow用户

发布于 2019-04-20 00:31:05

假设Terri旨在包含字符串范围,而不是减法操作,您可以创建范围的DataFrame,然后使用stack来受益于对公共索引的joining,以扩展原始框架。

代码语言:javascript
运行
复制
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)

代码语言:javascript
运行
复制
  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的行为将删除空值,因此您的范围不必是统一的长度。

票数 3
EN

Stack Overflow用户

发布于 2019-04-20 00:37:37

唯一有效的方法是,如果你开始的DataFrame的Terri列是一个字符串:

代码语言:javascript
运行
复制
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值添加1才能包括端点。为了方便起见,您可以定义自己的范围函数:

代码语言:javascript
运行
复制
def myRange(a, b):
    return range(a, b+1)

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

代码语言:javascript
运行
复制
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

最后,将此结果与原始DataFrame连接起来:

代码语言:javascript
运行
复制
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

同样的事情,简而言之:

代码语言:javascript
运行
复制
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"]
    )
)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55764452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档